关于分代回收

关于分代回收

import sys

a = [1, 2, 3]
b = [4, 5, 6]

ls1 = a.append(b)
ls2 = b.append(a)

print(sys.getrefcount(a))
print(sys.getrefcount(b))

引用计数a和b都是3

分代回收怎么执行的?最终会回收a和b两个变量是吗?

我a和b相互调用,是我的需要,为什么要回收呢?什么情况下才启动分代回收?

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
慕之熠_灿烈 2019-06-20 14:03:05

同学,您好。

分代回收是一种建立在标记清除技术之上、以空间换时间的垃圾收集方式,Python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,Python将内存分为了3“代”,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代),分别对应着3个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python垃圾收集机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。本例中的变量a,b最终也都会被加以回收。

程序中a和b之间虽然是相互调用的关系,但是外部再无其他的引用关系,且由于这两者的相互调用造成了各自所占用的内存空间无法释放(因为其引用计数不为0),所以要进行垃圾回收。

当引用计数和标记清除两大机制仍然无法对其进行垃圾回收的对象,Python将自动触发分代回收机制以释放对应的内存空间。

如果我的回答解决了你的疑惑,请采纳,祝学习愉快~~~



  • 提问者 洛奇丶大 #1
    那a和b最终是在三代中被回收的? 如果此时的a和b已经在第三代了 我又引用了a和b 这两个变量的计数器不是1 那么这两个变量是不是永远不会被回收
    2019-06-20 15:06:13
  • 慕之熠_灿烈 回复 提问者 洛奇丶大 #2
    针对您案例中的a和b,回收的过程是发生在标记清除机制环节,Python中进行标记清除需要通过两个容器来加以完成:死亡容器、存活容器,具体回收过程如下: (1)当a,b不再作为参数传递给sys.getrefcount( )方法时,引用计数分别为2,此时删除a、b (2)删除后,a的引用为1,b的引用为1,根据引用计数的规则,此时无法回收a,b的内存 (3)对执行删除操作后的每个引用-1,此时a的引用为0,b的引用也为0,将a,b放入死亡容器内 (4)遍历存活容器,查看是否有的存活容器引用了死亡容器内的对象,如果有就把该对象(注意是对象,而非对象的引用)从死亡容器内取出,放到存活容器内,由于a、b都没有对象引用他们了,所以至此,它们还是在死亡容器 (5)将死亡容器所有对象删除 这样就完成了对从a、b的垃圾回收。 Python中的垃圾回收机制引用计数、标记清除、分代回收三者协同工作以避免造成内存泄漏,本部分内容较为抽象,建议学员多思考,也可查阅资料辅助理解。 如果我的回答解决了你的疑惑,请采纳,祝学习愉快~~~
    2019-06-20 18:12:45
  • 提问者 洛奇丶大 回复 慕之熠_灿烈 #3
    你的第一步结尾 为什么就此时删除a和b了?我没有del操作啊
    2019-06-21 22:23:50
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
1.Python零基础入门
  • 参与学习           人
  • 提交作业       2727    份
  • 解答问题       8160    个

想要进入Python Web、爬虫、人工智能等高薪领域,你需要掌握本阶段的Python基础知识,课程安排带你高效学习轻松入门,学完你也能听得懂Python工程师的行业梗。

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师