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.collect() 的影响是未定义的。

gc.set_debug(flags)

设置垃圾回收调试标志。调试信息将写入 sys.stderr。有关可使用位操作组合以控制调试的调试标志列表,请参见下文。

gc.get_debug()

返回当前设置的调试标志。

gc.get_objects(generation=None)

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

在版本 3.8 中更改:新的 generation 参数。

引发 审计事件 gc.get_objects,其参数为 generation

gc.get_stats()

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

  • collections 是收集此代的次数;

  • collected 是在此代中收集的总对象数;

  • uncollectable 是在此代中发现无法收集的总对象数(因此被移动到 garbage 列表中)。

在版本 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)

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

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

警告

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

引发 审计事件 gc.get_referrers,参数为 objs

gc.get_referents(*objs)

返回任何参数直接引用的对象列表。返回的引用对象是参数的 C 级 tp_traverse 方法(如果存在)访问的对象,并且可能不是所有实际直接可访问的对象。 tp_traverse 方法仅受支持垃圾回收的对象支持,并且仅需要访问可能涉及循环的对象。因此,例如,如果整数可从参数直接访问,则该整数对象可能出现在结果列表中,也可能不出现。

引发 审计事件 gc.get_referents,参数为 objs

gc.is_tracked(obj)

如果对象当前由垃圾回收器跟踪,则返回 True,否则返回 False。一般来说,原子类型的实例不会被跟踪,非原子类型的实例(容器、用户定义的对象等)会被跟踪。但是,为了抑制简单实例(例如,仅包含原子键和值的字典)的垃圾回收器占用空间,可能会存在一些特定于类型的优化。

>>> 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()

冻结垃圾收集器跟踪的所有对象;将它们移动到一个永久代,并在所有未来的收集中忽略它们。

如果一个进程将 fork() 而没有 exec(),避免在子进程中进行不必要的写时复制将最大化内存共享并减少整体内存使用。这既需要避免在父进程的内存页中创建释放的“空洞”,又需要确保子进程中的 GC 收集不会触及源自父进程的长寿命对象的 gc_refs 计数器。为了实现这两点,请在父进程的早期调用 gc.disable(),在 fork() 之前调用 gc.freeze(),并在子进程的早期调用 gc.enable()

在版本 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 中。

gc.callbacks

垃圾回收器在回收之前和回收之后调用的回调列表。回调将使用两个参数调用,阶段信息

阶段可以是两个值之一

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

“stop”:垃圾回收已完成。

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

“generation”:正在回收的最早代。

“collected”:当阶段为“stop”时,成功回收的对象数量。

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

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

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

允许应用程序在 garbage 中出现时识别并清除自己的不可回收类型。

在版本 3.3 中添加。

为与 set_debug() 一起使用提供了以下常量

gc.DEBUG_STATS

在回收期间打印统计信息。在调整回收频率时,此信息可能很有用。

gc.DEBUG_COLLECTABLE

打印有关找到的可回收对象的的信息。

gc.DEBUG_UNCOLLECTABLE

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

在版本 3.2 中更改:如果 garbage 列表在 解释器关闭 时不为空,还打印其内容。

gc.DEBUG_SAVEALL

设置后,找到的所有不可访问对象将附加到垃圾中,而不是释放。这对于调试泄漏程序可能很有用。

gc.DEBUG_LEAK

收集器打印有关泄漏程序的信息所需的调试标志(等于 DEBUG_COLLECTABLE | DEBUG_UNCOLLECTABLE | DEBUG_SAVEALL)。