一、引用计数
当该对象的引用技术为0时,将被清除
1.1 引用+1的四种场景
第一,当对象被创建,a=1
第二,当对象被引用,b=a
第三,对象作为参数,传入到参数中fun(a)
第四,对象作为元素,存储到容器list=[“a”,1,2,4]
1.2 引用-1的四种场景
第一,该对象被销毁,del a
第二,该对象赋予新的值 a=26
第三,该对象离开作用域,函数fun执行完毕,函数里局部变量的引用计数器会减1
第四,该对象从容器中删除,或者这个容器被销毁
1.3 引用计数的优缺点
优点:
第一,高效
第二,实时性,一旦没有引用,内存就释放;处理回收内存分摊到平时
第三,对象有确定的生命周期
第四,易于实现
缺点:
第一,维护引用计数消耗资源,维持计数成本和引用赋值成正比
第二,无法解决循环引用的问题。A和B互相引用而没有外部引用
二、标记-清除
分两个阶段,第一个阶段是标记,把所有“活动对象”打上标记,第二阶段把没有标记的对象进行回收。
2.1 如何判断哪些是活动对象
对象之间的引用是通过指针连在一起,构成一个有向图。从根对象出发去遍历,可达的是活动对象,不可达的是非活动对象。
如上图,1,2,3是活动对象,4,5是非活动对象
2.2 优缺点
优点:
主要处理一些容器对象,如:列表、元组、字典、实例等【使用双向链表把这些对象连接起来】;
字符串、数值对象不可能造成循环引用;
缺点:
必须要扫描整个栈内存,哪怕只有一点活动对象也要全部扫描
三、分代回收
有三个代,年轻代,中年代,老年代,分别对应三个链表,收集频率随着存活时间的增加而减少;比如新创建的对象,放到年轻代中,年轻代总数达到上限后,触发回收机制,把可回收的回收掉,不可回收的放到中年代中,以此类推;是一种以空间换时间的操作,建立在标记-清除基础之上的一种技术。