【发布时间】:2013-12-10 13:32:43
【问题描述】:
Pythons gc.disable 禁用自动垃圾收集。据我了解,这会产生相当多的副作用。为什么会有人想要禁用自动垃圾收集,没有它怎么能有效地管理内存?
【问题讨论】:
Pythons gc.disable 禁用自动垃圾收集。据我了解,这会产生相当多的副作用。为什么会有人想要禁用自动垃圾收集,没有它怎么能有效地管理内存?
【问题讨论】:
禁用垃圾收集器的一个用途是在计时代码性能时获得更一致的结果。 The timeit module 这样做。
def timeit(self, number=default_number):
if itertools:
it = itertools.repeat(None, number)
else:
it = [None] * number
gcold = gc.isenabled()
gc.disable()
...
In Python2 和 Python3.2 gc.disable() 也用于避免 a bug caused by garbage collection occurring between fork and exec。问题似乎已在Python3.3 中得到解决,无需调用gc.disable()。
【讨论】:
从您链接到的同一页面:
由于收集器补充了已经使用的引用计数 Python,如果您确定您的程序,您可以禁用收集器 不会创建引用循环。
这就回答了问题的第二部分,“没有它,如何有效地管理内存”。不要创建参考循环。当然,这是一个相当有限的用例。
对于问题的第一部分,答案是性能。同样,这是一个相当有限的用例。
只有在以下情况下,禁用 GC 才会有帮助:(a) GC 确实在工作,并且 (b) 该工作没有取得任何成果,也就是说它没有找到任何可释放的内容,或者发现的内容太少以至于您认为程序可以容忍只要 GC 被禁用,泄漏。因此,如果您的程序太慢并且没有创建引用循环,并且禁用 GC 似乎可以加快速度,那么您可以考虑禁用 GC。
我推测(基于我之前看到的 GC,而不是 Python 的)如果你不分配任何内存,那么垃圾收集器不会有任何长期的性能成本。整理以前的东西可能会有一些短期和不可预测的成本。因此,即使您要进入大量的numpy 数字运算例程并认为您应该从该部分代码中挤出所有可能的性能,但在执行此操作时禁用 GC 仍然无济于事。它只会延迟整理先前参考周期的时间成本,直到您重新启用 GC。
可以说,运行时间短且不使用太多内存的程序不需要垃圾收集,它们可以容忍泄漏。但更有争议的是,如果您一开始有这样的想法,您最终会遇到一个泄漏比您预期更多的内存的程序的麻烦。
【讨论】:
启用 GC 的问题始终是您不知道何时它会发生。因此,如果您的程序(部分)时间紧迫,需要实时等,那么您可以在程序运行期间(部分)禁用 GC。
您是否想稍后再次打开自动 GC,或者您是否更愿意通过调用 gc.collect() 手动执行此操作,与该问题无关。
另外,有些程序被设计为只能运行很短的时间,因此开发人员可以确保在此期间不会发生任何内存问题(考虑像ls这样的程序);那么可以忽略整个 GC 方面以提高性能。
【讨论】:
另一个用例是使用 gc.collect() 手动控制垃圾回收
【讨论】:
gc.collect() 的要求吗?或者gc.collect() 的用例是什么? (注意:实际上我过去曾在一个 C# 应用程序中遇到过这样的用例,该应用程序在
gc.collect() AFAIK。