28.12. gc —垃圾收集器界面

该模块提供了到可选垃圾收集器的接口。它提供了禁用收集器,调整收集频率以及设置调试选项的Function。它还提供对收集器找到但无法释放的无法访问对象的访问。由于收集器补充了已经在 Python 中使用的引用计数,因此如果您确定程序未创建引用循环,则可以禁用收集器。可以pass调用gc.disable()禁用自动收集。要调试泄漏的程序,请调用gc.set_debug(gc.DEBUG_LEAK)。请注意,这包括gc.DEBUG_SAVEALL,导致将垃圾收集的对象保存在 gc.garbage 中以进行检查。

gc模块提供以下Function:

  • gc. enable ( )

    • 启用自动垃圾收集。
  • gc. disable ( )

    • 禁用自动垃圾收集。
  • gc. isenabled ( )

    • 如果启用了自动收集,则返回 true。
  • gc. collect([* generation *])

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

在版本 2.5 中更改:添加了可选的* generation *参数。

在 2.6 版中进行了更改:在运行完整的集合或最高代(2)的集合时,将清除为多种内置类型维护的空闲列表。由于特定的实现,尤其是intfloat,并非所有空闲列表中的所有项目都可能被释放。

  • gc. set_debug(* flags *)

    • 设置垃圾收集调试标志。调试信息将被写入sys.stderr。请参阅下面的调试标志列表,可以使用位操作来组合调试标志以控制调试。
  • gc. get_debug ( )

    • 返回当前设置的调试标志。
  • gc. get_objects ( )

    • 返回收集器跟踪的所有对象的列表,但不包括返回的列表。

2.2 版中的新Function。

  • gc. set_threshold(*阈值 0 * [,*阈值 1 * [,*阈值 2 *]])
    • 设置垃圾收集阈值(收集频率)。将阈值 0 设置为零将禁用收集。

GC 根据对象存活的收集扫描次数将其分为三代。新对象放置在最年轻的一代(第0代)中。如果对象在集合中幸存下来,则将其移入下一代。由于世代2是最古老的世代,因此该世代中的对象将在收集后保留在那里。为了确定何时运行,收集器会跟踪自上次收集以来的数字对象分配和释放。当分配数量减去取消分配数量超过* threshold0 时,收集开始。最初仅检查0世代。如果自检查世代1以来检查了世代0超过阈值 1 次以上,则也要检查世代1。类似地,* threshold2 *在收集世代2之前控制世代1的集合数。

  • gc. get_count ( )
    • 返回当前集合计数为(count0, count1, count2)的 Tuples。

2.5 版的新Function。

  • gc. get_threshold ( )

    • (threshold0, threshold1, threshold2)Tuples 的形式返回当前收集阈值。
  • gc. get_referrers(** objs *)

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

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

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

2.2 版中的新Function。

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

2.3 版的新Function。

  • 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

2.7 版的新Function。

为只读访问提供了以下变量(您可以更改其值,但不能重新绑定它):

  • gc. garbage
    • 收集器发现无法访问但无法释放的对象列表(无法收集的对象)。默认情况下,此列表仅包含具有del()方法的对象。 [1]具有del()方法并且属于参考循环的对象导致整个参考循环无法收集,包括对象不一定在该循环中,而是只能从该循环访问。 Python 不会自动收集此类循环,因为通常来说,Python 不可能猜测出运行del()方法的安全 Sequences。如果您知道安全订单,可以pass检查垃圾列表并明确break该列表中的对象所导致的周期来强制执行此问题。请注意,即使这些对象由于位于* garbage 列表中而仍然保持活动状态,因此也应将它们从 garbage 中删除。例如,在break循环后,执行del gc.garbage[:]以清空列表。通常最好pass不使用del()方法创建包含对象的循环来避免该问题,在这种情况下可以检查 garbage *以验证是否没有创建此类循环。

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

提供以下常量供set_debug()使用:

  • gc. DEBUG_STATS

    • 在收集期间打印统计信息。调整收集频率时,此信息可能很有用。
  • gc. DEBUG_COLLECTABLE

    • 在找到的可收集对象上打印信息。
  • gc. DEBUG_UNCOLLECTABLE

    • 打印找到的无法收集的对象(无法到达但无法被收集器释放的对象)的信息。这些对象将被添加到garbage列表中。
  • gc. DEBUG_INSTANCES

  • gc. DEBUG_OBJECTS

  • gc. DEBUG_SAVEALL

    • 设置后,找到的所有无法访问的对象将附加到垃圾中,而不是被释放。这对于调试泄漏的程序很有用。
  • gc. DEBUG_LEAK

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

Footnotes

  • [1]
    • 在 Python 2.2 之前的版本中,该列表包含所有无法访问周期的实例对象,而不仅仅是具有del()方法的实例对象。