【问题标题】:Why disable the garbage collector?为什么禁用垃圾收集器?
【发布时间】:2013-12-10 13:32:43
【问题描述】:

Pythons gc.disable 禁用自动垃圾收集。据我了解,这会产生相当多的副作用。为什么会有人想要禁用自动垃圾收集,没有它怎么能有效地管理内存?

【问题讨论】:

    标签: python garbage-collection


    【解决方案1】:

    禁用垃圾收集器的一个用途是在计时代码性能时获得更一致的结果。 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 Python2Python3.2 gc.disable() 也用于避免 a bug caused by garbage collection occurring between fork and exec。问题似乎已在Python3.3 中得到解决,无需调用gc.disable()

    【讨论】:

      【解决方案2】:

      从您链接到的同一页面:

      由于收集器补充了已经使用的引用计数 Python,如果您确定您的程序,您可以禁用收集器 不会创建引用循环。

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

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

      只有在以下情况下,禁用 GC 才会有帮助:(a) GC 确实在工作,并且 (b) 该工作没有取得任何成果,也就是说它没有找到任何可释放的内容,或者发现的内容太少以至于您认为程序可以容忍只要 GC 被禁用,泄漏。因此,如果您的程序太慢并且没有创建引用循环,并且禁用 GC 似乎可以加快速度,那么您可以考虑禁用 GC。

      我推测(基于我之前看到的 GC,而不是 Python 的)如果你不分配任何内存,那么垃圾收集器不会有任何长期的性能成本。整理以前的东西可能会有一些短期和不可预测的成本。因此,即使您要进入大量的numpy 数字运算例程并认为您应该从该部分代码中挤出所有可能的性能,但在执行此操作时禁用 GC 仍然无济于事。它只会延迟整理先前参考周期的时间成本,直到您重新启用 GC。

      可以说,运行时间短且不使用太多内存的程序不需要垃圾收集,它们可以容忍泄漏。但更有争议的是,如果您一开始有这样的想法,您最终会遇到一个泄漏比您预期更多的内存的程序的麻烦。

      【讨论】:

      • 问题在于,在实践中,很难(几乎不可能)确保没有参考周期。您可以轻松地确保您的代码没有,但是您的依赖项呢?由于模块、函数和类通常不指定它们是否创建引用循环,因此您必须检查每个依赖项和传递依赖项(包括标准库)的代码并验证没有进行此类引用。当然,升级依赖项可能会引入一个循环。
      • @Kevin:绝对。我想我的意思是“相当有限”是一种具有讽刺意味的轻描淡写。
      【解决方案3】:

      启用 GC 的问题始终是您不知道何时它会发生。因此,如果您的程序(部分)时间紧迫,需要实时等,那么您可以在程序运行期间(部分)禁用 GC。

      您是否想稍后再次打开自动 GC,或者您是否更愿意通过调用 gc.collect() 手动执行此操作,与该问题无关。

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

      【讨论】:

        【解决方案4】:

        另一个用例是使用 gc.collect() 手动控制垃圾回收

        【讨论】:

        • 但是首先禁用 GC 是能够使用gc.collect() 的要求吗?或者gc.collect() 的用例是什么? (注意:实际上我过去曾在一个 C# 应用程序中遇到过这样的用例,该应用程序在
        • 没有。您可以随时致电gc.collect() AFAIK。
        猜你喜欢
        • 1970-01-01
        • 2011-10-15
        • 1970-01-01
        • 2023-03-07
        • 2022-01-12
        • 2020-01-21
        • 2010-11-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多