2020年12月5日21:47:35 王凯玉
python中的垃圾回收机制
引用计数
# 引用计数
引用计数是编程语言中的一中内存管理技术,可以将资源的被引用次数保存起来。
当引用计数为0时,资源将被释放
# 如何让引用计数减少
del语句会删除对象的一个引用,这将导致该引用指向的对象的引用计数-1
# 引用计数会导致什么问题
由于两个或多个对象相互引用时,彼此引用计数不为0,造成循环引用无法回收,但是可以用标记清除机制来解决。
# 如何查看引用计数
import sys
sys.getrefcount(obj)
标记清除
# 标记清除
标记清除分为两个阶段:先标记对象(垃圾检测)、再清除垃圾(垃圾回收)
# 标记
在这个阶段,垃圾回收器会先从根对象开始遍历,每一个可以从根对象访问到的对象都会被添加标记,这个对象就会被标识为可到达对象(不会被清除)
# 清除
这时候,垃圾回收器就会对堆内存从头到尾进行线性遍历,如果发现有对象没有被标识成可多达对象,就会把该对象回收,之后再讲原来标记为可到达对象的标识抹掉,以便进行下一次的垃圾回收操作。
# 标记清除有什么问题
标记清除算法最大的缺点就是垃圾收集后有可能造成大量的内存碎片,其次就是,由当遍历的内存节点较多时,每次回收都会花费很多的时间在遍历上。
# 常见的名词
collector:垃圾收集器
mutator:垃圾收集器之外的部分,比如当前的应用程序
mutator roots:是mutator的根对象,通常是分配在对内存之外,可以直接被访问到的对象,一般就是指静态的全局变量。
可到达对象:从根对象开始遍历,可以访问到的对象,也就是mutator正在使用的对象。
分代回收
# 分代回收
分代回收是一种典型的以空间换时间的技术。
简单说就是把回收对象分成多个代,比如青年代、中年代、老年代。每一个代都是一个集合。
当青年代满了的时候,就会对所有代执行标记清除动作,中年代满了,就会清理中年代和老年代,老年代满了只会清理自己(老年代的存活时间是最长的)