什么时候在python中收集垃圾?

时间:2012-02-26 00:39:23

标签: python memory-management garbage-collection

什么时候在python中收集垃圾?什么时候发布内存并且收集会影响性能?可以选择退出或调整gc算法,如果是这样的话?

3 个答案:

答案 0 :(得分:12)

以下是language reference

的摘录
  

永远不会明确销毁对象;然而,当它们变得无法到达时,它们可能被垃圾收集。 允许实现推迟垃圾收集或完全省略 - 只要没有收集到仍然可访问的对象,实现垃圾收集的实现质量问题就是如此。

     

CPython实现细节:CPython目前使用引用计数方案和(可选)延迟检测循环链接垃圾,一旦它们无法访问就收集大多数对象,但不保证收集包含循环引用的垃圾。有关控制循环垃圾收集的信息,请参阅gc模块的文档。其他实现的行为不同,CPython可能会改变。当对象无法访问时,不要依赖于对象的立即终结(例如:总是关闭文件)。

编辑:关于推迟垃圾收集.... gc模块允许您与垃圾收集器进行交互,如果您想要并且更改收集频率等,则禁用它。但我自己没有使用它。此外,包含__del__方法are not collected

的任何对象的循环

答案 1 :(得分:12)

什么时候在python中收集垃圾?

CPython的源代码中有很多细节:http://svn.python.org/view/python/trunk/Modules/gcmodule.c?revision=81029&view=markup

只要引用计数降至零,就会立即删除该对象。

  

293 / * Python的循环gc永远不会看到传入的引用计数

     

294 * 0:如果某事减少到0,那应该是

     

295 *当时立即解除分配。

当新对象的数量大于现有对象数量的25%时,将触发完整集合。

  

87除了各种可配置的阈值之外,我们只触发

     如果比例

,则完全收集88次      

89 long_lived_pending / long_lived_total

     

90高于给定值(硬连线至25%)。

什么时候释放内存?

我只能找到这些信息。

  

781 / *清除所有免费列表

     

782 *所有免费清单在收集最高时被清除   代。

     

783 *免费列表中的已分配项目可能会保留pymalloc竞技场   占据。

     

784 *清除空闲列表可能会提前向操作系统返回内存。

     

785 * /

根据这一点,Python可能会将您的对象保留在空闲列表中以进行回收,即使您将其引用计数降为零也是如此。我无法明确地找到何时进行免费调用以将内存返回给操作系统,但我想这是在收集完成并且对象没有保存在空闲列表中时完成的。

该集合是否会影响效果?

我听说过的任何非平凡的垃圾收集器都需要CPU和内存才能运行。因此,是的,总会对性能产生影响。你必须试验并了解你的垃圾收集器。

需要实时响应的程序我遇到了问题,因为垃圾收集器不允许我控制它们运行的​​时间或它们的运行时间。一些特殊情况也可能导致过多的内存使用,例如Python保留免费列表的诀窍。

答案 2 :(得分:1)

用更多数字和可操作信息来扩展之前的答案:

您可以使用 gc.set_threshold(threshold0[, threshold1[, threshold2]]) 来调整自动垃圾收集何时启动:

<块引用>

GC 将对象分为三代,具体取决于对象的数量 他们幸免于难。新对象放置在 最年轻的一代(第 0 代)。如果一个对象在集合中存活 它被移入下一个老一代。由于第 2 代是 最老的一代,那一代的对象在经过一段时间后仍然留在那里 收藏。为了决定何时运行,收集器会跟踪 自上次以来对象分配和释放的数量 收藏。当分配数减去分配数 解除分配超过阈值 0,收集开始。最初只有 检查第 0 代。如果第 0 代已被检查超过 从第 1 代开始检查阈值 1 次,然后第 1 代 1 也进行了检查。有了第三代,事情有点 更复杂,见Collecting the oldest generation for more information.

虽然我在文档中找不到默认阈值,但查看了实现,阈值的默认值 seem to be (CPython 3.9.1) :

  • threshold0:700
  • threshold1:10
  • threshold2:10

即默认情况下,一旦分配次数减去释放次数超过 700,就会设置自动垃圾回收。