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 参数。

引发一个带有参数 generation审计事件 gc.get_objects

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

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

如果一个进程在没有 exec() 的情况下 fork(),则避免子进程中不必要的写时复制将最大化内存共享并减少整体内存使用量。 这需要避免在父进程的内存页中创建释放的“漏洞”,并确保子进程中的 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

一个回调列表,垃圾回收器将在回收之前和之后调用这些回调。 将使用两个参数 phaseinfo 调用回调。

phase 可以是两个值之一

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

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

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

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

“collected”: 当 phase 为“stop”时,成功收集的对象数。

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

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

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

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

在 3.3 版本中新增。

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

gc.DEBUG_STATS

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

gc.DEBUG_COLLECTABLE

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

gc.DEBUG_UNCOLLECTABLE

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

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

gc.DEBUG_SAVEALL

设置后,找到的所有不可达对象都将附加到 garbage 而不是被释放。 这对于调试泄露的程序很有用。

gc.DEBUG_LEAK

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