python垃圾回收机制 简单分析一下python中的垃圾回收机制,主要从三方面阐述:引用计数、标记清除、分代回收。 引用计数 引用计数是什么? 引用计数是编程语言中的一种内存管理技术;将资源(可以是对象、内存或磁盘空间等)的引用次数保存起来 引用计数为零时,资源将被释放。 如何使引用计数减少? del语句会删除对象的一个引用,这会导致该引用指向的对象的引用计数减1 ==注意==:任何调试或追踪程序会给对象增加一个额外引用,这会推迟该对象的回收时间 引用计数会导致什么问题? 由于两个或以上对象互相引用时,彼此引用计数不为0, 造成循环引用而无法回收。 In [1]: a = [1] In [2]: b = [2] In [3]: a.append(b) In [4]: b.append(a) In [5]: a Out[5]: [1, [2, [...]]] In [6]: b Out[6]: [2, [1, [...]]] 如何查看引用计数? In [7]: import sys In [8]: sys.getrefcount(a) Out[8]: 15 In [9]: sys.getrefcount(b) Out[9]: 15 标记清除 Python引入了其它的垃圾回收机制来弥补引用计数的缺陷:"标记-清除" 『标记清除(Mark—Sweep)』算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。它分为两个阶段:第一阶段是标记阶段,GC会把所有的『活动对象』打上标记,第二阶段是把那些没有标记的对象『非活动对象』进行回收。那么GC又是如何判断哪些是活动对象哪些是非活动对象的呢? 对象之间通过引用(指针)连在一起,构成一个有向图,对象构成这个有向图的节点,而引用关系构成这个有向图的边。从根对象(root object)出发,沿着有向边遍历对象,可达的(reachable)对象标记为活动对象,不可达的对象就是要被清除的非活动对象。根对象就是全局变量、调用栈、寄存器。 在上图中,我们把小黑圈视为全局变量,也就是把它作为root object,从小黑圈出发,对象1可直达,那么它将被标记,对象2、3可间接到达也会被标记,而4和5不可达,那么1、2、3就是活动对象,4和5是非活动对象会被GC回收。 垃圾标记时(也就是检测循环引用时),先将集合中对象的引用计数复制一份副本(以免在操作过程中破坏真实的引用计数值) 这个计数副本的唯一作用是寻找root ...