模块篇:gc---垃圾回收器接口

此模块提供可选的垃圾回收器的接口,提供的功能包括:关闭收集器、调整收集频率、设置调试选项。它同时提供对回收器找到但是无法释放的不可达对象的访问。由于 Python 使用了带有引用计数的回收器,如果你确定你的程序不会产生循环引用,你可以关闭回收器。可以通过调用 gc.disable() 关闭自动垃圾回收。若要调试一个存在内存泄漏的程序,调用 gc.set_debug(gc.DEBUG_LEAK) ;需要注意的是,它包含 gc.DEBUG_SAVEALL ,使得被垃圾回收的对象会被存放在 gc.garbage 中以待检查。

模块提供下列函数:

  • gc.enable()
    启用自动垃圾回收
  • gc.disable()
    停用自动垃圾回收
  • gc.isenabled()
    如果启用了自动回收则返回 True。
  • gc.collect(generation=2)
    若被调用时不包含参数,则启动完全的垃圾回收。可选的参数 generation 可以是一个整数,指明需要回收哪一代(从 0 到 2 )的垃圾。当参数 generation 无效时,会引发 ValueError 异常。返回发现的不可达对象的数目。
    每当运行完整收集或最高代 (2) 收集时,为多个内置类型所维护的空闲列表会被清空。 由于特定类型特别是 float 的实现,在某些空闲列表中并非所有项都会被释放。
  • 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 列表中)。
  • gc.set_threshold(threshold0[, threshold1[, threshold2]])
    设置垃圾回收阈值(收集频率)。 将 threshold0 设为零会禁用回收。
    垃圾回收器把所有对象分类为三代,其依据是对象在多少次垃圾回收后幸存。 新建对象会被放在最年轻代(第 0 代)。 如果一个对象在一次垃圾回收后幸存,它会被移入下一个较老代。 由于第 2 代是最老代,这一代的对象在一次垃圾回收后仍会保留原样。 为了确定何时要运行,垃圾回收器会跟踪自上一次回收后对象分配和释放的数量。 当分配数量减去释放数量的结果值大于 threshold0 时,垃圾回收就会开始。 初始时只有第 0 代会被检查。 如果自第 1 代被检查后第 0 代已被检查超过 threshold1 次,则第 1 也会被检查。 对于第三代来说情况还会更复杂,请参阅 Collecting the oldest generation 来了解详情。
  • gc.get_count()
    将当前回收计数以形为 (count0, count1, count2) 的元组返回。
  • gc.get_threshold()
    将当前回收阈值以形为 (threshold0, threshold1, threshold2) 的元组返回。
  • gc.get_referrers(*objs)
    返回直接引用任意一个 ojbs 的对象列表。这个函数只定位支持垃圾回收的容器;引用了其它对象但不支持垃圾回收的扩展类型不会被找到。
    需要注意的是,已经解除对 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})
False
>>> gc.is_tracked({"a": []})
True
  • 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
  • gc.freeze()
    冻结 gc 所跟踪的所有对象 —— 将它们移至永久代并忽略所有未来的集合。 这可以在 POSIX fork() 调用之前使用以便令对写入复制保持友好或加速收集。 并且在 POSIX fork() 调用之前的收集也可以释放页面以供未来分配,这也可能导致写入时复制,因此建议在主进程中禁用 gc 并在 fork 之前冻结,而在子进程中启用 gc。
  • gc.unfreeze()
    解冻永久代中的对象,并将它们放回到年老代中。
  • gc.get_freeze_count()
    返回永久代中的对象数量。

以下变量仅供只读访问(你可以修改但不应该重绑定它们):
一个回收器发现不可达而又无法被释放的对象(不可回收对象)列表。 从 Python 3.4 开始,该列表在大多数时候都应该是空的,除非使用了含有非 NULL tp_del 空位的 C 扩展类型的实例。

  • gc.garbage
    如果设置了 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 中的不可回收类型的对象。

以下常量被用于 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)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354

推荐阅读更多精彩内容