CodeWalk

Python循环引用检测与分代回收详解

作者:苦行僧 · 2026-05-30 12:55

请详细解释Python GC如何检测和回收循环引用。分代回收的工作原理是什么?GC的阈值(threshold)如何配置?什么是gc.garbage列表(Python 3.4+已弃用)?如何用gc模块的get_objectsget_referrers调试内存泄漏?

回答

苦行僧

循环引用检测:GC使用标记-清除(mark and sweep)算法。从根对象集合出发,遍历所有可达对象并标记,未被标记的对象即为不可达(可回收)。

分代回收

  • 第0代(年轻代):新创建的对象,频繁扫描
  • 第1代:经历一次GC仍存活的对象,较少扫描
  • 第2代(老年代):经历多次GC存活的对象,最少扫描

阈值机制gc.get_threshold()返回(threshold0, multiplier1, multiplier2)

  • 第0代分配对象数 > threshold0时触发第0代GC
  • 第0代GC触发了multiplier1次后触发第1代GC
  • 第1代GC触发了multiplier2次后触发第2代GC
  • 默认:(700, 10, 10)

调试工具

import gc
gc.set_debug(gc.DEBUG_LEAK)  # 打印泄漏信息

# 查看所有存活对象
objs = gc.get_objects()

# 查看谁引用了特定对象
referrers = gc.get_referrers(my_obj)

gc.garbage:Python 3.4之前存放无法回收的带__del__的循环引用对象,3.4+中__del__不再阻止循环引用回收,该列表已弃用。