- Python垃圾回收机制处理循环引用的原理:
- Python使用引用计数为主,标记 - 清除和分代收集为辅的垃圾回收机制。引用计数是指每个对象都有一个引用计数器,记录有多少个变量引用了该对象。当引用计数变为0时,对象立即被回收。
- 对于循环引用,由于对象之间相互引用,它们的引用计数不会为0,这时引用计数无法处理。Python的标记 - 清除算法会在一定条件下(比如内存紧张等)启动,它会遍历所有对象,标记所有可达对象(从根对象出发能访问到的对象),然后清除所有未标记的对象,这些未标记的对象就是不可达的循环引用对象。
- 代码示例展示循环引用场景:
import gc
class A:
def __init__(self):
self.b = None
class B:
def __init__(self):
self.a = None
a = A()
b = B()
a.b = b
b.a = a
# 此时a和b形成了循环引用
del a
del b
# 显示地调用垃圾回收
collected = gc.collect()
print(f"回收的对象数量: {collected}")
- 垃圾回收机制处理后的结果:
- 在上述代码中,首先创建了
A
和B
类的实例a
和b
,并让它们相互引用,形成循环引用。
- 然后删除
a
和b
变量,此时对象a
和b
虽然相互引用,但它们在程序中已经没有外部引用(从全局变量空间无法访问到它们)。
- 调用
gc.collect()
显示地触发垃圾回收。垃圾回收机制通过标记 - 清除算法,会检测到这两个相互引用但不可达的对象,并将它们回收。gc.collect()
函数返回回收的对象数量,运行上述代码,会打印出回收的对象数量为2,即a
和b
这两个对象被成功回收。