Python的gc.disable
可以禁用自动垃圾回收。据我所知,这将产生相当多的副作用。为什么有人要禁用自动垃圾回收,并且在没有它的情况下如何有效地管理内存?
禁用垃圾收集器的一个用途是在测试代码性能时获得更加一致的结果。 使用timeit
模块可以实现这一点。
def timeit(self, number=default_number):
if itertools:
it = itertools.repeat(None, number)
else:
it = [None] * number
gcold = gc.isenabled()
gc.disable()
...
在Python2中以及直到Python3.2,也使用gc.disable()
来避免fork
和exec
之间垃圾回收所引起的错误。这个问题似乎在Python3.3中已经修复,而不需要调用gc.disable()
。
从您提供的页面中可以看到:
由于收集器补充了 Python 中已经使用的引用计数,如果您确定程序不会创建引用循环,可以禁用收集器。
这回答了问题的第二部分,“如何在没有它的情况下有效地管理内存”。不要创建引用循环。当然,这是一个相当有限的用例。
对于问题的第一部分,答案是性能。同样,这也是一个相当有限的用例。
如果(a)垃圾收集器实际上在工作,并且(b)该工作没有取得任何成果,即它没有找到任何可释放的内容或者发现很少,以至于您认为您的程序可以容忍暂时的泄漏而不需要收集,则禁用GC才会有所帮助。因此,如果您的程序太慢,并且不会创建引用循环,并且禁用 GC 看起来可以加快速度,那么您将考虑禁用 GC。
我推测(基于我之前见过的垃圾收集器,而不是特别针对 Python 的)如果您没有分配任何内存,那么垃圾收集器就不会有任何长期的性能成本。它可能会在清理之前有一些短期和不可预测的成本。因此,即使在您进入一个大规模的 numpy
数学计算程序,并认为应该从代码中挤出所有可能的性能时,禁用 GC 也是没有帮助的。它只会推迟清理之前的引用循环所需的时间成本,直到您重新启用 GC。
可以说,运行时间短且不占用太多内存的程序不需要垃圾回收,它们可以容忍泄漏。但更值得注意的是,如果您从一开始就这样思考,最终可能会遇到比预期泄露更多的内存程序而导致麻烦。
gc.collect()
手动控制垃圾回收。gc.collect()
的要求吗?或者gc.collect()
的用例是什么?(注意:我实际上曾经在一个C#应用程序中遇到过这样的用例,在<512MiB的框中内存不足) - Sebastian Mach