深入理解Python内存管理与垃圾回收,再也不怕问了(二)

Petra ·
更新时间:2024-11-10
· 816 次阅读

在这里插入图片描述

垃圾回收机制

来看一下Python中的垃圾回收技术:

引用计数为主 标记清除和分代回收为辅

如果一个对象的引用计数为0,Python解释器就会回收这个对象的内存,但引用计数的缺点是不能解决循环引用的问题,所以我们需要标记清除和分代回收。

什么是引用计数 每个对象都有存有指向该对象的引用总数 查看某个对象的引用计数sys.getrefcount() 可以使用del关键字删除某个引用 import sys l = [] print(sys.getrefcount(l)) # Output: 2 l2 = l l3 = l l4 = l3 print(sys.getrefcount(l)) # Output: 5 del l2 print(sys.getrefcount(l)) # Output: 4 i = 1 print(sys.getrefcount(i)) # Output: 140 a = i print(sys.getrefcount(i)) # Output: 141

当对象的引用计数达到零时,解释器会暂停,来取消分配它以及仅可从该对象访问的所有对象。即满足引用计数为0的时候,会启动垃圾回收。

但是引用计数不能解决循环引用的问题,就如下的代码不停跑就能把电脑内存跑满:

>>> a = [] >>> b = [] >>> while True: ... a.append(b) ... b.append(a) ... [1] 31962 killed python 标记清除

标记清除算法作为Python的辅助垃圾收集技术主要处理的是一些容器对象,比如list、dict、tuple,instance等,因为对于字符串、数值对象是不可能造成循环引用问题。标记清除分代回收就是为了解决循环引用而生的。

它分为两个阶段:第一阶段是标记阶段,GC会把所有的活动对象打上标记,第二阶段是把那些没有标记的对象非活动对象进行回收。

对象之间通过引用(指针)连在一起,构成一个有向图,对象构成这个有向图的节点,而引用关系构成这个有向图的边。从根对象(root object)出发,沿着有向边遍历对象,可达的(reachable)对象标记为活动对象,不可达的对象就是要被清除的非活动对象。根对象就是全局变量、调用栈、寄存器。

原创文章 61获赞 55访问量 1万+ 关注 私信 展开阅读全文
作者:宇宙之一粟



垃圾回收 Python

需要 登录 后方可回复, 如果你还没有账号请 注册新账号