当前位置:编程学习 > python >>

《Python源码剖析》读书笔记:内存垃圾回收

 

上篇:www.zzzyk.com/kf/201110/109227.html

Python内存回收的基石是引用计数,“当一个对象的引用被创建或复制时,对象的引用技术加1;当一个对象的引用被销毁时,对象的引用技术减1”,如果对象的引用计数减少为0,将对象的所占用的内存释放。

 

引用计数的缺点是对循环引用无能为力,优点是将内存释放的操作时机离散化,不会引起瞬间的易做图动。

Python采用Mark-Sweep算法来解决循环引用问题

Mark-Sweep过程

** 寻找root object集合,root object指全局引用和函数栈上的引用

** 从root object出发,通过其每一个引用到达的所有对象都标记为reachable(垃圾检测)

** 将所有非reachable的对象删除(垃圾回收)

 

垃圾检测只需要跟踪可以保有其他对象引用的container对象(例如list,dict,class,instance等)即可。

 

Python创建container对象时,会在前面加入PyGC_Head。通过PyGC_Head串起来的双向链表把所有container对象串起来。

Python的GC有分代机制,分3代。最年轻代到最老代默认个数是700/10/10,当某代里的对象数超过阈值,将会引发一次GC动作。某个对象在一次GC中存活的话,就把它移到更老的一代。

对象的引用计数存在PyGC_Head的ob_refcnt,GC时会使用此值的副本,PyGC_Head的gc.gc_refs

在垃圾检测过程中,会先试探地把所有对象的引用计数减1。遇到一个引用计数为0的对象,先将其标记为GC_TENTATIVELY_UNREACHABLE。如果之后某个对象的遍历过程中遇到这个临时标记的对象,证明它还是有引用的,将其移回reachable列表并且把引用计数设为1。

垃圾检测完成后,所有在unreachable链表的对象都可以释放了,除了那些定义了__del__方法的对象。之前一篇blog也提到,Python不会自动回收这些对象。  

摘自 不沉之月

补充:Web开发 , Python ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,