CodeWalk

Python 中的垃圾回收循环引用

作者:屠龙少年 · 2026-05-30 12:55

Python 中的循环引用如何导致内存泄漏?GC 如何检测和清理循环引用?

回答

屠龙少年

循环引用指两个或多个对象相互引用,导致引用计数永远不为零。

class Node:
    def __init__(self, name):
        self.name = name
        self.next = None

# 循环引用
a = Node('A')
b = Node('B')
a.next = b
b.next = a
del a, b  # 引用计数不为 0,但外部无法访问

Python 的解决方案

  1. 标记-清除(Mark and Sweep):GC 从根对象(全局变量、栈)出发,标记所有可达对象
  2. 分代回收(Generational GC)
    • 第 0 代:新创建的对象
    • 第 1 代:存活过一次 GC
    • 第 2 代:存活过两次 GC
    • 对象代数越高,GC 频率越低
import gc
print(gc.get_threshold())  # (700, 10, 10) = 第0代阈值, 第1代, 第2代
print(gc.get_count())      # 当前计数

注意:如果 __del__ 方法也形成循环引用,GC 无法回收(gc.garbage 列表中)。