28.12. gc — 垃圾收集器接口 — Python 文档
28.12. GC — 垃圾收集器接口
该模块为可选的垃圾收集器提供了一个接口。 它提供了禁用收集器、调整收集频率和设置调试选项的能力。 它还提供对收集器找到但无法释放的无法访问的对象的访问。 由于收集器补充了 Python 中已经使用的引用计数,如果您确定您的程序不会创建引用循环,您可以禁用收集器。 可以通过调用 gc.disable()
来禁用自动收集。 调试泄漏的程序调用 gc.set_debug(gc.DEBUG_LEAK)
。 请注意,这包括 gc.DEBUG_SAVEALL
,导致垃圾收集对象保存在 gc.garbage 中以供检查。
gc 模块提供以下功能:
- gc.enable()
- 启用自动垃圾收集。
- gc.disable()
- 禁用自动垃圾收集。
- gc.isenabled()
- 如果启用了自动收集,则返回 true。
- gc.collect([generation])
没有参数,运行一个完整的集合。 可选参数 generation 可以是一个整数,指定要收集哪一代(从 0 到 2)。 如果生成编号无效,则会引发
ValueError
。 返回找到的不可达对象的数量。2.5 版更改: 添加了可选的 generation 参数。
- gc.set_debug(flags)
- 设置垃圾回收调试标志。 调试信息将写入
sys.stderr
。 请参阅下面的调试标志列表,这些标志可以使用位操作组合来控制调试。
- gc.get_debug()
- 返回当前设置的调试标志。
- gc.get_objects()
返回收集器跟踪的所有对象的列表,不包括返回的列表。
2.2 版中的新功能。
- gc.set_threshold(threshold0[, threshold1[, threshold2]])
设置垃圾收集阈值(收集频率)。 将 threshold0 设置为零会禁用收集。
GC 将对象分为三代,具体取决于它们幸存的集合扫描次数。 新对象放置在最年轻的代(代
0
)中。 如果一个对象在一个集合中幸存下来,它就会被移动到下一个老年代。 由于第2
代是最老的一代,因此该代中的对象在收集后仍保留在那里。 为了决定何时运行,收集器会跟踪自上次收集以来对象分配和释放的数量。 当分配次数减去释放次数超过 threshold0 时,收集开始。 最初只检查第0
代。 如果自检查代1
以来检查代0
的次数超过 threshold1,则还检查代1
。 同样,threshold2控制代1
在采集代2
之前采集的次数。
- gc.get_count()
将当前集合计数作为
(count0, count1, count2)
的元组返回。2.5 版中的新功能。
- gc.get_threshold()
- 将当前收集阈值作为
(threshold0, threshold1, threshold2)
的元组返回。
- gc.get_referrers(*objs)
返回直接引用任何 obj 的对象列表。 该函数只会定位那些支持垃圾回收的容器; 不会找到引用其他对象但不支持垃圾收集的扩展类型。
请注意,已被取消引用但仍处于循环中且尚未被垃圾收集器收集的对象可以在结果引用者中列出。 要仅获取当前活动的对象,请在调用 get_referrers() 之前调用 collect()。
使用 get_referrers() 返回的对象时必须小心,因为其中一些可能仍在构建中,因此处于暂时无效状态。 避免将 get_referrers() 用于调试以外的任何目的。
2.2 版中的新功能。
- gc.get_referents(*objs)
返回任何参数直接引用的对象列表。 返回的指涉对象是参数的 C 级 tp_traverse 方法(如果有)访问的对象,并且可能不是所有实际直接可访问的对象。 tp_traverse 方法只有支持垃圾收集的对象才支持,并且只需要访问可能参与循环的对象。 因此,例如,如果可以从参数直接访问整数,则该整数对象可能会或可能不会出现在结果列表中。
2.3 版中的新功能。
- gc.is_tracked(obj)
如果对象当前被垃圾收集器跟踪,则返回
True
,否则返回False
。 作为一般规则,原子类型的实例不会被跟踪,非原子类型(容器、用户定义的对象……)的实例会被跟踪。 但是,可以存在一些特定于类型的优化以抑制简单实例的垃圾收集器占用空间(例如 dicts 只包含原子键和值):>>> gc.is_tracked(0) False >>> gc.is_tracked("a") False >>> gc.is_tracked([]) True >>> gc.is_tracked({}) False >>> gc.is_tracked({"a": 1}) False >>> gc.is_tracked({"a": []}) True
2.7 版中的新功能。
以下变量用于只读访问(您可以改变其值,但不应重新绑定):
- gc.garbage
收集器发现无法访问但无法释放的对象列表(不可收集的对象)。 默认情况下,此列表仅包含具有
__del__()
方法的对象。 1 具有__del__()
方法并且是引用循环的一部分的对象会导致整个引用循环无法收集,包括不一定在循环中但只能从循环中访问的对象。 Python 不会自动收集此类循环,因为一般而言,Python 不可能猜测运行__del__()
方法的安全顺序。 如果你知道一个安全的顺序,你可以通过检查 garbage 列表来强制这个问题,并且由于列表中的对象而明确地打破循环。 请注意,即使如此,由于在 garbage 列表中,这些对象仍然保持活动状态,因此它们也应该从 garbage 中删除。 例如,在中断循环后,执行del gc.garbage[:]
以清空列表。 通常最好避免使用__del__()
方法创建包含对象的循环,并且在这种情况下可以检查 garbage 以验证没有创建此类循环。如果设置了 DEBUG_SAVEALL,则所有无法访问的对象都将添加到此列表中而不是释放。
提供了以下常量用于 set_debug():
- gc.DEBUG_STATS
- 在收集期间打印统计信息。 此信息在调整收集频率时非常有用。
- gc.DEBUG_COLLECTABLE
- 打印有关找到的可收集对象的信息。
- gc.DEBUG_UNCOLLECTABLE
- 打印找到的不可收集对象的信息(无法访问但收集器无法释放的对象)。 这些对象将被添加到
garbage
列表中。
- gc.DEBUG_INSTANCES
- 当设置了 DEBUG_COLLECTABLE 或 DEBUG_UNCOLLECTABLE 时,打印有关找到的实例对象的信息。
- gc.DEBUG_OBJECTS
- 当设置了 DEBUG_COLLECTABLE 或 DEBUG_UNCOLLECTABLE 时,打印关于找到的实例对象以外的对象的信息。
- gc.DEBUG_SAVEALL
- 设置后,所有找到的无法访问的对象将被附加到 garbage 而不是被释放。 这对于调试泄漏程序很有用。
- gc.DEBUG_LEAK
- 收集器打印有关泄漏程序的信息所需的调试标志(等于
DEBUG_COLLECTABLE | DEBUG_UNCOLLECTABLE | DEBUG_INSTANCES | DEBUG_OBJECTS | DEBUG_SAVEALL
)。
脚注
- 1
- 在 Python 2.2 之前,列表包含无法访问循环中的所有实例对象,而不仅仅是那些具有
__del__()
方法的实例对象。