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 使用一个双向链表将这些容器对象组织起来。不过,这种简单粗暴的标记清除算法也有明显的缺点:清除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。

posted @ 2022-10-28 10:47  非非非常帅的辰  阅读(84)  评论(1编辑  收藏  举报