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。返回已回收对象和不可回收对象的总和。

调用 gc.collect(0) 将对年轻代执行一次垃圾回收。

调用 gc.collect(1) 将对年轻代执行一次垃圾回收,并对老年代执行一次增量回收。

调用 gc.collect(2)gc.collect() 将执行一次完整回收。

每当运行完整回收或最高代 (2) 的回收时,都会清除为一些内置类型维护的自由列表。由于具体实现的原因,某些自由列表中的所有项可能不会被释放,特别是 float

在解释器已经在执行回收时调用 gc.collect() 的效果是未定义的。

在 3.14 版本发生变更: generation=1 会执行一次增量回收。

gc.set_debug(flags)

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

gc.get_debug()

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

gc.get_objects(generation=None)

返回回收器跟踪的所有对象的列表,不包括返回的列表本身。如果 generation 不是 None,则只返回以下对象:

  • 0: 年轻代中的所有对象

  • 1: 没有对象,因为(自 Python 3.14 起)没有第 1 代

  • 2: 老年代中的所有对象

在 3.8 版本发生变更: 新增 generation 形参。

在 3.14 版本发生变更: 第 1 代被移除。

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

gc.get_stats()

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

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

  • collected 是在这一代中回收的对象总数;

  • uncollectable 是在这一代中被发现是不可回收的(因此被移到 garbage 列表)的对象总数。

在 3.4 版本加入。

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

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

GC 根据对象是否在一次回收中幸存下来,将它们分为两代。新对象被放置在年轻代。如果一个对象在一次回收中幸存下来,它就会被移到老年代。

为了决定何时运行,回收器会跟踪自上次回收以来的对象分配和释放次数。当分配次数减去释放次数超过 threshold0 时,回收开始。每次回收时,会回收年轻代中的所有对象和老年代中的一部分对象。

在 free-threaded 构建版本中,运行回收器之前还会检查进程内存使用量的增加情况。如果自上次回收以来内存使用量没有增加 10%,并且对象分配的净数量没有超过 threshold0 的 40 倍,则不会运行回收。

回收的老年代部分与 threshold1 成**反比**。threshold1 越大,老年代中的对象被回收得越慢。对于默认值 10,每次回收会扫描 1% 的老年代。

threshold2 被忽略。

有关更多信息,请参阅 垃圾回收器设计

在 3.14 版本发生变更: threshold2 被忽略。

gc.get_count()

(count0, count1, count2) 的元组形式返回当前回收计数。

gc.get_threshold()

(threshold0, threshold1, threshold2) 的元组形式返回当前回收阈值。

gc.get_referrers(*objs)

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

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

警告

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

引发一个附带参数 objs审计事件 gc.get_referrers

gc.get_referents(*objs)

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

引发一个附带参数 objs审计事件 gc.get_referents

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

一个回调函数列表,将在垃圾回收前后被调用。回调函数将以两个参数 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)。