refchain的上一个对象
refchain的下一个对象
引用计数器:每个对象都有引用计数器,创建之后默认为1,引用的时候加1
类型
值
根据不同的类型创建不同的结构体:PyObject,PyVarObject
回收将对象从refchain链表删除,将对象销毁,内存归还
标记清除 解决循环引用的问题
循环引用链表存放:list/tuple/dict/set
将可以能存在循环引用的对象维护成3个链表:
0:对象到700扫描
1:0代扫描10次,1代扫描1次
2:1代扫描10次,2代扫描1次
在python中维护了一个rechain的双向环状链表,这个链表存储创建的所有对象,每种类型的对象都具有一个引用计数器,默认为1,只要引用次数就加1,最后当引用计数器为0时进行垃圾回收(在rechain中删除,对象销毁)
但是当在list/tuple/set/dict这种由多个元素组成的对象可能会存在循环引用的问题,为了解决这个问题使用了标记清除和分代回收,其内部为4个链表:refchain,0代700个,1代是0代的10倍,2代是1代的10倍
当源码内部达到各自的阈值时,就会触发扫描链表进行标记清除操作,有循环则各自减1
普通对象用refchain,多个对象用refchain+3代
为了避免重复创建和销毁一些常见对象,维护池
比如启动解释器时会先自动创建整型的相关对象,这样取得时候只需要从缓存池中取即可
v1 = 7v2 = 6v3 = 6print(id(v1))print(id(v2))print(id(v3))
free_list当一个对象得引用计数器为0时,按理说就应该直接回收,但是内部不会直接回收,而是将对象添加到free_list链表中当缓存,以后在创建对象时,不在重新开辟内存,而是直接使用free_list
v1 = 3.14 # 开辟内存,内部存储结构体中定义那几个值,并存到refchain中del v1 # refchain中移除,在将对象添加到free_list中v9 = 999.99 # 不会重新开辟内存,去free_list中获取对象,对象内部数据初始化,在放到refchain中
参考资料https://www.bilibili.com/video/BV1dp4y1C7ja