gc — 垃圾收集器接口 — Python 文档

来自菜鸟教程
Python/docs/3.9/library/gc
跳转至:导航、​搜索

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=2)

没有参数,运行一个完整的集合。 可选参数 generation 可以是一个整数,指定要收集哪一代(从 0 到 2)。 如果生成编号无效,则会引发 ValueError。 返回找到的不可达对象的数量。

每当运行完整集合或最高代 (2) 的集合时,就会清除为许多内置类型维护的空闲列表。 由于特定的实现,并非某些空闲列表中的所有项目都可能被释放,特别是 float

gc.set_debug(flags)
设置垃圾回收调试标志。 调试信息将写入sys.stderr。 请参阅下面的调试标志列表,这些标志可以使用位操作组合来控制调试。
gc.get_debug()
返回当前设置的调试标志。
gc.get_objects(generation=None)

返回收集器跟踪的所有对象的列表,不包括返回的列表。 如果 generation 不是 None,则仅返回该代中收集器跟踪的对象。

3.8 版更改: 新增 参数。

gc.get_stats()

返回包含自解释器启动以来收集统计信息的三个每代字典的列表。 将来可能会更改键的数量,但目前每个字典将包含以下项目:

  • collections是这一代被收集的次数;

  • collected为本代内收集的对象总数;

  • uncollectable 是这一代中被发现无法收集(因此被移至 垃圾 列表)的对象总数。

3.4 版中的新功能。

gc.set_threshold(threshold0[, threshold1[, threshold2]])

设置垃圾收集阈值(收集频率)。 将 threshold0 设置为零会禁用收集。

GC 将对象分为三代,具体取决于它们幸存的集合扫描次数。 新对象放置在最年轻的代(代 0)中。 如果一个对象在一个集合中幸存下来,它就会被移动到下一个老年代。 由于第 2 代是最老的一代,因此该代中的对象在收集后仍保留在那里。 为了决定何时运行,收集器会跟踪自上次收集以来对象分配和释放的数量。 当分配次数减去释放次数超过 threshold0 时,开始收集。 最初只检查第 0 代。 如果自检查代 1 以来检查代 0 的次数超过 threshold1,则还检查代 1。 到了第三代,事情就有点复杂了,更多信息参见收集最老的一代

gc.get_count()
将当前集合计数作为 (count0, count1, count2) 的元组返回。
gc.get_threshold()
将当前收集阈值作为 (threshold0, threshold1, threshold2) 的元组返回。
gc.get_referrers(*objs)

返回直接引用任何 obj 的对象列表。 该函数只会定位那些支持垃圾回收的容器; 不会找到引用其他对象但不支持垃圾收集的扩展类型。

请注意,已被取消引用但仍处于循环中且尚未被垃圾收集器收集的对象可以在结果引用者中列出。 要仅获取当前活动的对象,请在调用 get_referrers() 之前调用 collect()

警告

使用 get_referrers() 返回的对象时必须小心,因为其中一些可能仍在构建中,因此处于临时无效状态。 避免将 get_referrers() 用于除调试以外的任何目的。

gc.get_referents(*objs)
返回任何参数直接引用的对象列表。 返回的指涉对象是参数的 C 级 tp_traverse 方法(如果有)访问的那些对象,并且可能不是所有实际可直接访问的对象。 tp_traverse方法只有支持垃圾收集的对象才支持,并且只需要访问可能参与循环的对象。 因此,例如,如果可以从参数直接访问整数,则该整数对象可能会或可能不会出现在结果列表中。
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

3.1 版中的新功能。

gc.is_finalized(obj)

如果给定对象已被垃圾收集器终结,则返回 True,否则返回 False

>>> x = None
>>> class Lazarus:
...     def __del__(self):
...         global x
...         x = self
...
>>> lazarus = Lazarus()
>>> gc.is_finalized(lazarus)
False
>>> del lazarus
>>> gc.is_finalized(x)
True

3.9 版中的新功能。

gc.freeze()

冻结 gc 跟踪的所有对象 - 将它们移动到永久代并忽略所有未来的集合。 这可以在 POSIX fork() 调用之前使用,以使 gc 写时复制友好或加快收集速度。 此外,在 POSIX fork() 调用之前收集可能会释放页面以供将来分配,这也可能导致写时复制,因此建议在父进程中禁用 gc 并在 fork 之前冻结并在子进程中启用 gc。

3.7 版中的新功能。

gc.unfreeze()

解冻永久代中的对象,将它们放回最老的代。

3.7 版中的新功能。

gc.get_freeze_count()

返回永久代中的对象数。

3.7 版中的新功能。

为只读访问提供了以下变量(您可以改变这些值,但不应重新绑定它们):

gc.garbage

收集器发现无法访问但无法释放的对象列表(不可收集的对象)。 从 Python 3.4 开始,这个列表大部分时间应该是空的,除非使用带有非 NULL tp_del 槽的 C 扩展类型的实例。

如果设置了 DEBUG_SAVEALL,则所有无法访问的对象都将添加到此列表中而不是释放。

3.2 版更改: 如果此列表在 解释器关闭 时为非空,则会发出 ResourceWarning,默认情况下是静默的。 如果设置了 DEBUG_UNCOLLECTABLE,还会打印所有不可收集的对象。

在 3.4 版更改:遵循 PEP 442,具有 __del__() 方法的对象不会最终出现在 gc.garbage[ X132X] 了。

gc.callbacks

垃圾收集器在收集前后将调用的回调列表。 将使用两个参数调用回调,phaseinfo

phase 可以是以下两个值之一:

“start”:垃圾收集即将开始。

“停止”:垃圾收集已经完成。

info 是一个为回调提供更多信息的字典。 当前定义了以下键:

“generation”:被收集的最老的一代。

“已收集”:当phase为“停止”时,成功收集的对象数。

“uncollectable”:当phase为“stop”时,无法回收并放入garbage的对象数。

应用程序可以将自己的回调添加到此列表中。 主要用例是:

收集有关垃圾收集的统计信息,例如收集各代的频率以及收集所需的时间。

当它们出现在 garbage 中时,允许应用程序识别和清除它们自己的不可收集类型。

3.3 版中的新功能。

提供了以下常量用于 set_debug()

gc.DEBUG_STATS
在收集期间打印统计信息。 此信息在调整收集频率时非常有用。
gc.DEBUG_COLLECTABLE
打印有关找到的可收集对象的信息。
gc.DEBUG_UNCOLLECTABLE

打印找到的不可收集对象的信息(无法访问但收集器无法释放的对象)。 这些对象将被添加到 garbage 列表中。

在 3.2 版更改: 如果 interpreter shutdown 不为空,还打印 garbage 列表的内容。

gc.DEBUG_SAVEALL
设置后,所有找到的无法访问的对象将被附加到 garbage 而不是被释放。 这对于调试泄漏程序很有用。
gc.DEBUG_LEAK
收集器打印有关泄漏程序的信息所需的调试标志(等于 DEBUG_COLLECTABLE | DEBUG_UNCOLLECTABLE | DEBUG_SAVEALL)。