扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
这篇文章给大家分享的是Python中GC的垃圾回收算法的使用,相信大部分人都还没学会这个技能,为了让大家学会,给大家总结了以下内容,话不多说,一起往下看吧。
成都创新互联是一家集网站建设,花都企业网站建设,花都品牌网站建设,网站定制,花都网站建设报价,网络营销,网络优化,花都网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。一、引用计数
刚开始学习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的垃圾回收算法的使用就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流