Python 为什么要禁用垃圾收集器?

Python 为什么要禁用垃圾收集器?,python,garbage-collection,Python,Garbage Collection,Pythons禁用自动垃圾收集。据我所知,这会有相当多的副作用。为什么会有人想禁用自动垃圾回收,没有它怎么能有效地管理内存?禁用垃圾回收器的一个用途是在对代码性能计时时获得更一致的结果。这样做 def timeit(self, number=default_number): if itertools: it = itertools.repeat(None, number) else: it = [None] * number gcold =

Pythons禁用自动垃圾收集。据我所知,这会有相当多的副作用。为什么会有人想禁用自动垃圾回收,没有它怎么能有效地管理内存?

禁用垃圾回收器的一个用途是在对代码性能计时时获得更一致的结果。这样做

def timeit(self, number=default_number):
    if itertools:
        it = itertools.repeat(None, number)
    else:
        it = [None] * number
    gcold = gc.isenabled()
    gc.disable()
    ...

并且最多使用
gc.disable()
来避免。该问题似乎已在中修复,无需调用
gc.disable()

另一个用例是从链接到的同一页面使用
gc.collect()
手动控制垃圾收集:

由于收集器补充了中已使用的参考计数 Python,如果您确信您的程序 不创建引用循环

这就回答了问题的第二部分,“没有它,如何有效地管理内存”。不要创建引用循环。当然,这是一个相当有限的用例

对于问题的第一部分,答案是性能。同样,这是一个相当有限的用例

禁用GC只有在以下情况下才有帮助:(a)GC确实在工作,(b)工作没有取得任何成果,也就是说它找不到任何东西可以释放,或者发现的东西太少,以至于您认为只要禁用GC,您的程序就可以容忍泄漏。所以,如果你的程序太慢,没有创建参考循环,并且禁用GC来加速它,那么你会考虑禁用GC。 我推测(基于我之前看到的GC,特别是Python),如果不分配任何内存,垃圾收集器将不会有任何长期性能成本。它可能会有一些短期和不可预测的成本来收拾过去的一切。因此,即使是在您进入一个大规模的
numpy
数字处理例程的情况下,您也应该考虑从代码的这一部分中挤出所有可能的性能,在您这样做的同时禁用GC仍然没有帮助。它只会延迟整理以前引用周期的时间成本,直到重新启用GC之后


可以说,运行时间短且占用内存少的程序不需要垃圾收集,它们可以容忍泄漏。但更具争议性的是,如果你一开始就这样想,你最终会因为一个程序泄漏的内存比你预期的要多而陷入麻烦。

启用GC的问题总是在于你不知道什么时候会发生。因此,如果(程序的一部分)是时间关键型的,需要实时的,等等,那么您可以在(程序的该部分)运行时禁用GC

不管您是想稍后再次打开自动GC,还是想通过调用
GC.collect()
手动打开自动GC,都与这个问题无关


此外,有些程序设计为只在很短的时间内运行,因此开发人员可以确保在这段时间内不会出现任何内存问题(考虑以下程序);那么,为了提高性能,可以忽略整个GC方面。

但是首先禁用GC是能够使用
GC.collect()
的要求吗?或者,
gc.collect()
的用例是什么?(注意:我过去在一个C#应用程序中实际有过这样的用例,它在一个No上内存不足。您可以随时调用
gc.collect()
。问题是,在实践中,这很困难(几乎不可能)确保没有引用循环。您可以轻松地确保代码没有引用循环,但依赖项呢?由于模块、函数和类通常不会指定它们是否创建引用循环,因此您必须检查每个依赖项和可传递依赖项(包括标准库)的代码当然,升级依赖项可能会引入一个循环。@凯文:当然。我想我的意思是“相当有限”是一种讽刺的轻描淡写。