Python 内存回收机制

th.jpg

Python 内存回收涉及三个概念: 引用计数,标记-清除,分代回收

引用计数

当一个对象的引用计数为0时,回收该对象。GC 模块使用这种方法,编译器必须实时监控程序中对象的状态,一旦发现计数为0,立即释放对象的空间。虽然简单但是编译器的工作量比较大。

标记-清除

在引用计数的基础上,解决循环引用的问题。
所谓循环引用是指两个对象互相引用,甚至自己引用自己a = [] ; a.append[a],a列表存储了指向自己的引用,释放a时,要先释放a中的元素(将元素引用的计数减一),但是a的元素是又引用了a,因此要释放这个元素,就必须先释放a本身,如此便产生了循环,结果a始终得不到释放。
标记-清除:不改动真实计数,而是生成对象计数的一个副本,对该副本进行操作。副本的作用是寻找root object的集合(该集合中的对象不能被回收)。使用两条链表,一条维护root object,称root链表,一条维护剩下的对象,称unreachable 链表,遍历标记unreachable链表,如果其中有被root链表中对象引用的对象,就把它移到root链表里面。标记后 unreachable 链表中的所有对象都是垃圾对象。

分代回收

为了减轻解释器的负载,Python采用分代回收:0,1,2代,对应3条链表。
基本原则是存活越久的对象,不是垃圾的可能性越高,越减少对它的检查。
新创建的对象放在0号链表,按一定频率扫描,可以看出0代扫描最频繁,1代次之,2代最低。通过 gc.get_threshold()函数可以发现(700, 10, 10),默认当0代对象超过700个时触发检查,1代和2代超过10个时触发检查。
0代触发清理所有3代,1代触发清理1、2代,2代触发只清理2代。

你可能感兴趣的:(Python 内存回收机制)