python中有自动内存回收机制,一般情况不需要程序员来处理,面试时被大佬问到了,记录一下。
gc方式1:引用计数
若此对象无其他对象引用,则立马回收掉
优点:简单、实时(将处理垃圾时间分摊到运行代码时,而不是等到一次回收)
缺点:
1.保存对象引用数会占用一点点内存空间
2.每次执行语句都可能更新引用数,不再使用大的数据结构时,会引起大量对象被回收
3.不能处理循环引用的情况
gc方式2:标记-清除(Mark—Sweep)
此方式主要用来处理循环引用的情况,只有容器对象(list、dict、tuple,instance)才会出现循环引用的情况
循环引用示例:
处理过程
1.将所有容器对象放到一个双向链表中(链表为了方便插入删除),这些对象为0代 2.循环遍历链表,如果被本链表内的对象引入,自身的被引用数-1,如果被引用数为0,则触发引用计数回收条件,被回收掉 3.未被回收的对象,升级为1代
触发条件:
因为循环引用的原因,并且因为你的程序使用了一些比其他对象存在时间更长的对象,从而被分配对象的计数值与被释放对象的计数值之间的差异在逐渐增长。一旦这个差异累计超过某个阈值,则Python的收集机制就启动了,并且触发上边所说到的零代算法,释放“浮动的垃圾”,并且将剩下的对象移动到一代链表。
随着时间的推移,一代链表越来越多,多到触发gc阈值,同样会对一代链表进行标记清除操作,然后将剩下活跃对象升为二代
何时触发
1.被引用为0时,立即回收当前对象
2.达到了垃圾回收的阈值,触发标记-清除
3.手动调用gc.collect()
4.Python虚拟机退出的时候