title: python垃圾回收机制
date: 2020-12-15
tags:
python基础–垃圾回收机制
一.引用计数
1.引用计数是计算机编程语言中的一种内存管理技术**,是指将资源(可以是对象、内存或磁盘空间等等)的被引用次数保存起来,当被引用次数变为零时就将其释放的过程。
2.在引用计数中,每一个对象负责维护对象所有引用的计数值。当一个新的引用指向对象时,引用计数器就递增,当去掉一个引用时,引用计数就递减。当引用计数到零时,该对象就当做垃圾释放占有的资源。
3.代码实现:
import sys
a = []
# 两次引用,一次来自 a,一次来自 getrefcount
print(sys.getrefcount(a))
def func(a):
# 四次引用,a,python 的函数调用栈,函数参数,和 getrefcount
print(sys.getrefcount(a))
func(a)
# 两次引用,一次来自 a,一次来自 getrefcount,函数 func 调用已经不存在
print(sys.getrefcount(a))
注意:
-
sys.getrefcount() 函数用于查看一个变量的引用次数,不过别忘了,getrefcount 本身也会引入一次计数。
-
在函数调用发生的时候,会产生额外的两次引用,一次来自函数栈,另一个是函数参数。
4.del语句会删除对象的一个引用,将该引用指向的对象引用计数减1
import sys class Prosen: pass p = Prosen() # +1 p2 = p # +1 del p2 # -1 print(sys.getrefcount(p)) # +1
注意:任何追踪或调试程序会给对象增加一个额外引用,这会推迟该对象被回收的时间
二.标记清除
1.标记清除(Mark—Sweep)算法是一种基于追踪回收(tracing GC)技术实现的垃圾回收算法。它分为两个阶段:第一阶段是标记阶段,GC会把所有的活动对象打上标记,第二阶段是把那些没有标记的对象非活动对象进行回收。
2.标记清除有效解决了引用计数中由于两个或两个以上对象相互引用时,彼此引用计数不为0,造成循环引用而无法回收的问题。
三.分代回收
1.分代是一种典型的以空间换时间的技术:对象存在时间越长,越不可能是垃圾,应该越少收集,是解决内存遍历时间太久而诞生的解决方案。
2.分代就是将回收对象分为数个代,比如青年代,中年代,老年代。每个代都是一个链表(集合)当青年代满时,将触发清理所有三代,执行标记清除,当中年代满时,将触发清理中年代,老年代;最后,老年代只会触发清理自己。老年代存活时间是最长的。