在线客服
扫描二维码
下载博学谷APP扫描二维码
关注博学谷微信公众号
相信大家在面试中常常会碰到有关垃圾回收的问题,的确,Python和其他很多编程语言一样,都自带垃圾回收机制。本文主要和大家来分析一下Python中的垃圾回收算法。首先我们要知道,GC计算机术语指的是垃圾回收。而Python中的垃圾回收是以引用计数为主,但是为了弥补其算法的不足,所以又引入了标记-清除和分代收集算法为辅。
一、引用计数
刚开始学习Python的时候总是会有人告诉你,万物皆对象是一大特色。在Python中每一个对象的核心就是一个结构体PyObject,它的内部有一个引用计数器(ob_refcnt)。
// object.h
struct _object {
Py_ssize_t ob_refcnt; # 引用计数值
struct PyTypeObject *ob_type;
} PyObject;
引用计数的意思就是,一个对象在它刚被New出来呱呱(gugu不是guagua)坠地的时候因为被New方法引用了所以他的引用计数就是1,如果它被引用(也就是在之前的基础上 例如:b=a,被丢入函数列表等等被引用就会在引用计数上加1),如果引用它的对象被删除的时候(在之前的基础上DEL b)那么它的引用计数就会减少一一直到当它的引用计数变为0的时候,垃圾回收机制就会找上门做掉它(回收),脑补一下 :开门我是查水表的。
优点:高效,易于实现,实时性。一旦没有引用,内存就直接释放了。处理回收内存的时间分摊到了平时,对象有确定的生命周期。
缺点:维护性高,虽然简单实时,但是额外占用了一部分资源,虽然逻辑简单,但是比较麻烦。另外它还有不能解决的情况:--->循环引用,如下所示:
a=[1,2]
b=[2,3]
a.append(b)
b.append(a)
DEL a
DEL b
二、标记-清除算法
标记-清除就是用来解决循环引用的问题的只有容器对象才会出现引用循环,比如列表、字典、类、元组。 首先,为了追踪容器对象,需要每个容器对象维护两个额外的指针, 用来将容器对象组成一个链表,指针分别指向前后两个容器对象,方便插入和删除操作。试想一下,现在有两种情况:
A:
a=[1,3]
b=[2,4]
a.append(b)
b.append(a)
del a
del b
B:
a=[1,3]
b=[2,4]
a.append(b)
b.append(a)
del a
在标记-清除算法中,有两个集中营,一个是root链表,另外一个是unreachable链表。对于情景A,原来再未执行DEL语句的时候,a,b的引用计数都为2,但是在DEL执行完以后,a,b引用次数互相减1。a,b陷入循环引用的圈子中,然后标记-清除算法开始出来做事,找到其中一端a,开始拆这个a,b的引用环,去掉以后发现,a,b循环引用变为了0,所以a,b就被处理到unreachable链表中直接被做掉。
对于情景B,简单一看那b取环后引用计数还为1,但是a取环,就为0了。这个时候a已经进入unreachable链表中,已经被判为死刑了,但是这个时候,root链表中有b。如果a被做掉,那世界上还有什么正义... ,在root链表中的b会被进行引用检测引用了a,如果a被做掉了,那么b就...凉凉,一审完事,二审a无罪,所以被拉到了root链表中。
三、分代回收算法
了解分类回收,首先要了解一下,GC的阈值,所谓阈值就是一个临界点的值。随着你的程序运行,Python解释器保持对新创建的对象,以及因为引用计数为零而被释放掉的对象的追踪。从理论上说,创建==释放数量应该是这样子。但是如果存在循环引用的话,肯定是创建>释放数量,当创建数与释放数量的差值达到规定的阈值的时候,分代回收机制就开始起作用了。
垃圾回收=垃圾检测+释放。Python将所有的对象分为0,1,2三代;所有的新建对象都是0代对象;当某一代对象经历过垃圾回收,依然存活,就被归入下一代对象。Python在创建对象之前,会创建一个链表,零代链表,只不过这个链表是空的。每当你创建一个对象,Python便会将其加入到零代链表。
以上就是Python中GC的垃圾回收算法分析,大家都看懂了吗?如果对于引用计数,标记-清除和分代收集算法还有什么问题,可以上博学谷官网咨询在线老师,进行更为深入细致的学习。
— 申请免费试学名额 —
在职想转行提升,担心学不会?根据个人情况规划学习路线,闯关式自适应学习模式保证学习效果
讲师一对一辅导,在线答疑解惑,指导就业!
相关推荐 更多
人工智能+Python核心编程在线学习内容有什么?
人工智能+Python核心编程在线学习内容有什么?人工智能+Python核心编程分为四个阶段,主要学习Python基础、数据分析库Pandas、科学计算库numpy、Matplotlib绘图。核心编程课程适用零编程基础学员、python编程基础薄弱的学员、对机器学习感兴趣的学员、对深度学习感兴趣的学员学习。
6834
2019-07-24 11:43:29
Python知识点讲解之Python冒号的使用
本文要讲解Python的知识点是Python冒号。我们都知道,逗号“,”分隔各个维度,“:”表示各个维度内的切片,只有:表示取这个维度的全部值。那么下面小编有一个例子来详细分析下Python冒号的使用。
18168
2019-08-01 20:41:32
Python调试常见异常汇总
在调试Python程序过程中,难免会遇到各种各样的异常情况。一般情况下,异常可能是因为开发者在编写程序的时候疏漏或者考虑不周全导致的。在开发过程中异常是不可避免的,当你遇到异常的时候回立刻反应他的问题所在吗?为了让大家更好的认识这些常见的异常,博学谷小编将Python调试过程中会产生的异常进行了整理。推荐大家收藏。
6359
2019-10-29 14:56:21
Python为什么这么火?编程零基础该如何学习Python?
Python为什么这么火?编程零基础该如何学习Python?其实Python的火爆不是偶然,时代的潮流驱动也好,自身的语言优势也好,对于零基础的学习者来说,学习Python都是最好的选择。至于Python学习方式有很多,看书、报培训班都是比较靠谱的,看大家适应哪种学习模式。
5935
2019-11-20 13:21:14
创建表并给某个字段添加数据的SQL语句怎么写
创建表并给某个字段添加数据的SQL语句怎么写?创建表并给字段插入数据我们会使用到create table .. select 语句,学习SQL需要能够写出创建表并给某个字段添加数据的SQL语句。
4089
2022-01-24 14:45:05