Python内存管理与垃圾回收机制详解
请解释Python的内存管理机制,包括引用计数、标记-清除(Mark and Sweep)、分代回收(Generational GC)以及如何排查内存泄漏。
回答
小字辈
内存管理三层面:
-
引用计数(Reference Counting):
- 每个对象维护
ob_refcnt,有新的引用时+1,删除时-1 - 计数归零时立即回收内存
- 缺点:无法处理循环引用
- 每个对象维护
-
标记-清除(Mark and Sweep):
- 从根对象(全局变量、栈帧引用)出发,遍历所有可达对象并标记
- 未标记的对象(不可达)视为垃圾并回收
- 解决循环引用问题
-
分代回收(Generational GC):
- 对象分三代:0代(新生)、1代、2代(老生)
- 新创建对象在0代,GC频率最高
- 存活过一轮GC的对象晋升到下一代
- 阈值触发:
gc.get_threshold()返回(700, 10, 10),即0代分配700个对象触发GC
排查内存泄漏:
import gc
# 查看无法回收的对象
gc.set_debug(gc.DEBUG_LEAK)
gc.collect() # 手动触发GC
# 查看对象引用
import objgraph
objgraph.show_backrefs([leaky_object], max_depth=5)
# 使用tracemalloc
import tracemalloc
tracemalloc.start()
snapshot1 = tracemalloc.take_snapshot()
# ... 运行可疑代码 ...
snapshot2 = tracemalloc.take_snapshot()
stats = snapshot2.compare_to(snapshot1, 'lineno')
常见泄漏原因:未关闭的文件句柄、全局缓存无限增长、闭包捕获大对象、循环引用中的__del__方法。