Python垃圾回收机制(笔记)
仅仅供自己复习使用,勿喷
Python垃圾回收机制是一种引用计数为主,分代回收+标记清除为辅的一种回收机制
引用计数
在Python中,任何对象在python内部都会对其计数+1
例如①:a=1(赋值)
②:def func(a)(作为参数传入函数)
③:list = [a,a](放在容器内)
④:b = a(对象被引用)
相反的如果出现下面的情况,计数便会-1
例如①:del a
②从容器中被删除对象
所以当一个对象的引用计数为0时,python会自动将其回收,对象占用的内存空间就会被释放
但是如果一个对象被循环引用,下图代码
1 def f2(): 2 '''循环引用''' 3 c1=A() 4 c2=A() 5 c1.t=c2 6 c2.t=c1 7 del c1 8 del c2
以上情况中,C1=A(),C2=A()后引用计数会+1,此时又对其相互赋值,两者再次+1,这时候C1和C2引用计数就是2了,所以在进行del的时候,不会直接为0,而是变成1。
虽然它们两个的对象都是可以被销毁的,但是由于循环引用,导致垃圾回收器都不会回收它们,所以就会导致内存泄露
分代回收
python将内存根据对象的存活时间划分为三代,分别是0代,1代,2代,最开始被创建的对象会被分配至0代中,当0代中对象满了,python垃圾回收机制就会被回收
0代中没有被回收的对象转移到1代中,
以此类推,一般到2代中的对象是存活最久的对象,甚至长期存在在生命周期中
标记清除
标记清除是一种基于追踪回收的一种垃圾回收算法
每个对象之间,是有指针指向的有向图,python会由根节点出发,沿着指针出发,遍历全部对象。
标记清楚有两步
第一部:将会从根节点出发,对每个对象进行访问,如果能访问到,就会进行标记,没访问到则不标记
第二部:把没有被标记的对象进行回收
标记清除算法作为 Python 的辅助垃圾收集技术主要处理的是一些容器对象,比如 list、dict、tuple,instance 等,因为对于字符串、数值对象是不可能造成循环引用问题。Python 使用一个双向链表将这些容器对象组织起来。不过,这种简单粗暴的标记清除算法也有明显的缺点:清除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。