"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）。如果 generation 值无效将引发 "ValueError"。返回已回收对象
   和不可回收对象的总和。

   调用 "gc.collect(0)" 将在青年代上执行 GC 收集。

   调用 "gc.collect(1)" 将在青年代上执行 GC 收集并对老年代进行一次增量
   回收。

   调用 "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：没有对象，因为已没有第 1 代（对于 Python 3.14 来说）

   * 2：在老年代中的所有对象

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

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

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

gc.get_stats()

   返回一个包含三个字典对象的列表，每个字典分别包含对应代的从解释器开
   始运行的垃圾回收统计数据。字典的键的数目在将来可能发生改变，目前每
   个字典包含以下内容：

   * "collections" 是该代被回收的次数；

   * "collected" 是该代中被回收的对象总数；

   * "uncollectable" 是在这一代中被发现无法收集的对象总数（因此被移动
     到 "garbage" 列表中）。

   Added in version 3.4.

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

   设置垃圾回收阈值（收集频率）。将 *threshold0* 设为零会禁用回收。

   GC 根据对象是否在回收中幸存下来将其分为两代。新对象被放置在青年代中
   。如果一个对象在回收中幸存下来，则将其移动到老年代中。

   为了决定何时运行，回收器会跟踪自上次回收以来对象分配和释放的数量。
   当分配数减去释放数超过 *threshold0* 时，启动回收。每次回收都会回收
   青年代的所有对象和老年代的一部分对象。

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

   被回收的老年代数据的比例与 *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* 的对象列表。这个函数只定位支持垃圾回收
   的容器；引用了其它对象但不支持垃圾回收的扩展类型不会被找到。

   需要注意的是，已经解除对 *objs* 引用的对象，但仍存在于循环引用中未
   被回收时，仍然会被作为引用者出现在返回的列表当中。若要获取当前正在
   引用 *objs* 的对象，需要调用 "collect()" 然后再调用
   "get_referrers()"。

   警告:

     在使用 "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})
      True

   Added in version 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

   Added in version 3.9.

gc.freeze()

   冻结由垃圾回收器追踪的所有对象；将它们移至永久代并在所有未来的回收
   操作中忽略它们。

   如果一个进程将执行 "fork()" 而不执行 "exec()"，则在子进程中避免不必
   要的写入时拷贝将最大化内存共享并减少总体内存使用。 这需要同时在父进
   程的内存页中避免创建已释放的“空洞”并确保在子进程中的 GC 回收不会触
   及源自父进程的长寿对象的 "gc_refs" 计数器。 要同时达成这两个目标，
   请在父进程中尽早调用 "gc.disable()"，在 "fork()" 之前调用
   "gc.freeze()"，并在子进程中尽早调用 "gc.enable()"。

   Added in version 3.7.

gc.unfreeze()

   解冻永久代中的对象，并将它们放回到年老代中。

   Added in version 3.7.

gc.get_freeze_count()

   返回永久代中的对象数量。

   Added in version 3.7.

提供以下变量仅供只读访问（你可以修改但不应该重绑定它们）：

gc.garbage

   一个回收器发现不可达而又无法被释放的对象（不可回收对象）列表。从
   Python 3.4 开始，该列表在大多数时候都应该是空的，除非使用了含有非
   "NULL" "tp_del" 空位的 C 扩展类型的实例。

   如果设置了 "DEBUG_SAVEALL"，则所有不可访问对象将被添加至该列表而不
   会被释放。

   在 3.2 版本发生变更: 当 *interpreter shutdown* 即解释器关闭时，若此
   列表非空，会产生 "ResourceWarning" ，默认情况下此警告是静默的。如果
   设置了 "DEBUG_UNCOLLECTABLE"，所有无法被回收的对象会被打印。

   在 3.4 版本发生变更: 根据 **PEP 442**，具有 "__del__()" 方法的对象
   不会再出现在 "gc.garbage" 中。

gc.callbacks

   在垃圾回收器开始前和完成后会被调用的一系列回调函数。这些回调函数在
   被调用时使用两个参数： *phase* 和 *info* 。

   *phase* 可为以下两值之一：

      "start": 垃圾回收即将开始。

      "stop": 垃圾回收已结束。

   *info* 是一个字典，提供了回调函数更多信息。已有定义的键有：

      "generation"（代）：正在被回收的最久远的一代。

      "collected"（已回收的）：当 *phase* 为 "stop" 时，被成功回收的对
      象的数目。

      "uncollectable"（不可回收的）：当 *phase* 为 "stop" 时，不能被回
      收并被放入 "garbage" 的对象的数目。

   应用程序可以把自己的回调函数加入此列表。主要的使用场景有：

      统计垃圾回收的数据，如：不同代的回收频率、回收所花费的时间。

      使应用程序可以识别和清理自身在 "garbage" 中的不可回收类型的对象
      。

   Added in version 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").
