引用计数器
环状双向链表refchain
在python中创建的任何对象都会放在refchain链表中。
name='hanw'
#内部创建一些数据 结构体:【上一个对象,下一个对象,数据类型,引用个数,值('hanw')】
myname = name #name引用计数加1
data = 3.14 #创建一个float变量
'''
_ob_next
_ob_prev
ob_refcnt = 1
ob_type = float
ob_fval = 3.14
'''
引用计数
对象引用计数为0,进行垃圾回收。
1.对象从refchain链表移除。2.将对象销毁,内存释放。
a = 123
b = a #refcnt + 1
del b #refcnt - 1
标记清除
标记清除的触发条件???清除代价???
目的:为了解决引用计数器循环引用的不足。
实现:再维护一个链表,链表中专门存放循环引用的对象。(可变数据类型)
#循环引用示例
v1 = [11,22,33]
v2 = [44,55,66]
v1.append(v2)
v2.append(v1)
del v1
del v2
分代回收
根据对象的存活时间将变量分为3代,即将可能存在循环引用的对象维护成3个链表:
- 0代(年轻代):0代中对象个数达到700个扫描1次。
- 1代(中年代):0代扫描10次,则1代扫描1次。
- 2代(老年代):1代扫描10次,则2代扫描1次。
缓存
池:为了避免重复创建和销毁一些常见对象,维护池。
summary
在python中维护了一个refchain的双向环状链表,这个链表中存储程序创建的所有对象,每种类型的对象中都有一个ob_refcnt引用计数器的值,引用计数变为0时会对对象进行垃圾回收。(对象销毁,refchain中移除)
对于循环引用造成的内存泄漏问题,python引入标记清除和分代回收。