Python的垃圾回收机制主要是以引用计数为主和分代回收为辅的结合机制,当对象的引用计数为0时,对象就会被销毁掉。
引用计数
+1的情况
- 对象创建时
num = 1
print(sys.getrefcount(num))
print: 187
复制代码
这里23这个对象并没有在内存中创建,因为Python启动解释器的时候会创建一个小整数池,-5~256之间的这些对象,会被自动创建加载到内存中等待调用,num=1只是给这个整数的增加了一个引用
- 对象被引用
num = 1
num1 = num
print(sys.getrefcount(num))
print(sys.getrefcount(num1))
print: 188
188
复制代码
- 对象被作为参数,传入到一个函数中
def temp_print(a):
print(sys.getrefcount(a))
num = 1
num1 = num
temp_print(num)
print(sys.getrefcount(num))
print(sys.getrefcount(num1))
190
188
188
复制代码
传入函数的时候会增加一次引用,执行完毕后又会减少一次引用
4。 对象作为一个元素,存储到容器中
def temp_print(a):
print(sys.getrefcount(a))
num = 1
num1 = num
temp_print(num)
num_list = [num, num1]
print(sys.getrefcount(num))
print(sys.getrefcount(num1))
190
190
190
复制代码
-1的情况
- 对象的别名被赋予新的对象
num = 1
num1 = num
print(sys.getrefcount(num))
num1 = 2
print(sys.getrefcount(num))
188
187
复制代码
- 对象的别名被销毁
num = 1
num1 = num
print(sys.getrefcount(num))
del num1
print(sys.getrefcount(num))
188
187
复制代码
- 一个对象离开了它的作用域
- 对象所在的容器被销毁,或从容器中删除对象
num = 1
num1 = num
data_num = [num, num1]
print(sys.getrefcount(num))
del data_num
print(sys.getrefcount(num))
190
188
复制代码
标记删除
主要是解决循环引用的数据,由于它的引用大于0,所以不会回收
num = ["hello", "world"]
num1 = ["hi", "are", "you"]
print(sys.getrefcount(num))
print(sys.getrefcount(num1))
num.append(num1)
num1.append(num)
print(sys.getrefcount(num))
print(sys.getrefcount(num1))
del num
del num1
复制代码
由于删除后num num1的引用次数仍然为1,所以不会删除
标记删除就是为了解决这个循环引用的无法删除
步骤:
- 对删除操作后的每个引用-1, 此时num, num1的引用为0,把他们放到死亡容器里面,如果它的引用还是大于0就放到存活容器里
- 遍历存活容器,查看是否有的存活容器引用了死亡容器的对象,如果有的话,就把该对象从死亡容器内取出,放到存活容器里。
- 讲死亡容器里的所有对象全部删除
分代回收
- 新创建的对象为0代
- 每执行一个标记删除,存活的对象就加1
- 代数越高的对象,进行标记删除的时间间隔就越长
讲系统中的全部内存块依据其存活时间划分不同的集合,每个集合就成为一个“代”,垃圾收集的频率随着“代”的存活时间的增大而减少
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)