京公网安备 11010802034615号
经营许可证编号:京B2-20210330
python 垃圾收集机制的实例详解
这篇文章主要介绍了python垃圾收集机制的实例详解的相关资料,希望通过本文能帮助大家理解这部分内容,需要的朋友可以参考下
pythonn垃圾收集方面的内容如果要细讲还是挺多的,这里只是做一个大概的概括
Python最主要和绝大多数时候用的都是引用计数,每一个PyObject定义如下:
#define PyObject_HEAD \
Py_ssize_t ob_refcnt; \
struct _typeobject *ob_type;
typedef struct _object {
PyObject_HEAD
} PyObject;
每个pyobject都有一个refcnt来记录他们自己的引用数,一旦引用数为0,就进行回收
引用计数的优点在于实时性,一旦没有其他对象引用了,就能立马进行回收,看起来十分不错,但为什么好多语言都没有采用该方案,因为引用计数有一个致命的缺点,无法解决循环引用问题,比如:
a = []
b = []
a.append(b)
b.append(a)
其实并没有其他变量引用a,b那么他们实际上应该被回收掉,但由于相互引用的关系,他们的引用数都为1,无法被回收。
在python中,相互引用的问题仅仅存在与容器里面,例如list,dictionary,class,instance。为了解决该问题,python引入了标记——清除和分代——回收另外两种机制。
事实上,python中的容器并没有之前讲的那么简单,在pyobject_head之前,还有一个PyGC_head,也就是专门用来处理容器的循环引用问题的。
typedef union _gc_head {
struct {
union _gc_head *gc_next;
union _gc_head *gc_prev;
Py_ssize_t gc_refs;
} gc;
long double dummy; /* force worst-case alignment */
} PyGC_Head;
所有创建的容器类的对象都会被记录到可收集对象链表中,通过上面的结构我们可以知道其实是构建了一个双向链表,这样我们就可以来跟踪所有可能产生循环引用的情况了。而像int,string等简单的不是容器类型的,只要引用技术为0,就会被回收。但是如果频繁的malloc和free会严重影响效率,所以python采用了大量的对象池来提高效率。
标记——清除包括了垃圾回收的两个方面:(1)寻找可以回收的对象(2)回收对象,python中的标记会从root object开始,遍历所有容器类对象,查找出可以通过引用来到达的一些对象,把他们放到由reachable维护的链表中,对于不能到达的放到unbreachable维护的链表中,此过程结束之后,对unreachable里面的元素进行回收即可。
那么如何对应之前循环引用的情况呢?python里面会产生一个有效的引用数,存在gc.gc_refs里面,像上面的a,b真实引用数为1,但有效的引用数为0(循环中的引用数都减1),由于不能直接改pyobjec里面的refcnt,否则会产生一系列问题,我们可以将有效的引用数记到gc.gc_refs里面,那么a,b 的真实有效引用数都为0,所以他们可以被回收。
下面是另外一种情况:
a = []
b = []
c = a
a.append(b)
b.append(a)
这里ab也是循环引用,但是多了c来引用a,通过计算循环中的有效引用计数可得a的引用数为1,b的引用数为0,看起来b应该被回收,但实际上因为a是不可被回收的,a又引用了b,所以b也会被放入在reachable链表中,不被回收,其gc.gc_refs还是会被置1的。
另外一种分代回收,是说内存中有的对象会频繁的malloc和free,有的则比较长久,如果一个对象经过多次垃圾收集和清除之后还存在的话,那么我们就可以认为,这个对象是长时间有用的,不用去频繁检测回收它。python中分为3代,分别是3个链表维护,0代最多维护700个对象,1代10个,2代10个,如果对象超过这个数了,就会调用标记——清除算法来进行回收。可以想到,0代的对象经过一段时间后会到1代2代中去,然后对它们的检测回收会相比于0代的不那么频繁了
要注意的是,python主要的机制还是引用技术,标记——清除和分代收集只是为了弥补引用计数的缺点而添加的,也就是说,后两者基本只在容器类的循环引用上能发挥作用
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
主讲人简介 张冲,海归统计学硕士,CDA 认证数据分析师,前云南白药集团资深数据分析师,自媒体 Python 讲师,全网课程播放量破 ...
2026-04-10在数据可视化与业务分析中,同比分析是衡量业务发展趋势、识别周期波动的核心手段,其核心逻辑是将当前周期数据与上年同期数据进 ...
2026-04-10在机器学习模型的落地应用中,预测精度并非衡量模型可靠性的唯一标准,不确定性分析同样不可或缺。尤其是在医疗诊断、自动驾驶、 ...
2026-04-10数据本身是沉默的,唯有通过有效的呈现方式,才能让其背后的规律、趋势与价值被看见、被理解、被运用。统计制图(数据可视化)作 ...
2026-04-10在全球化深度发展的今天,跨文化传播已成为连接不同文明、促进多元共生的核心纽带,其研究核心围绕“信息传递、文化解读、意义建 ...
2026-04-09在数据可视化领域,折线图是展示时序数据、趋势变化的核心图表类型之一,其简洁的线条的能够清晰呈现数据的起伏规律。Python ECh ...
2026-04-09在数据驱动的时代,数据分析早已不是“凭经验、靠感觉”的零散操作,而是一套具备固定逻辑、标准化流程的系统方法——这就是数据 ...
2026-04-09长短期记忆网络(LSTM)作为循环神经网络(RNN)的重要改进模型,凭借其独特的门控机制(遗忘门、输入门、输出门),有效解决了 ...
2026-04-08在数据分析全流程中,数据质量是决定分析结论可靠性的核心前提,而异常值作为数据集中的“异类”,往往会干扰统计检验、模型训练 ...
2026-04-08在数字经济飞速发展的今天,数据已渗透到各行各业的核心场景,成为解读趋势、优化决策、创造价值的核心载体。而数据分析,作为挖 ...
2026-04-08在数据分析全流程中,数据处理是基础,图形可视化是核心呈现手段——前者负责将杂乱无章的原始数据转化为干净、规范、可分析的格 ...
2026-04-07在数据分析与统计推断中,p值是衡量假设检验结果显著性的核心指标,其本质是在原假设(通常为“无效应”“无差异”)成立的前提 ...
2026-04-07在数字经济深度渗透的今天,数据已成为企业生存发展的核心资产,企业的竞争本质已转变为数据利用能力的竞争。然而,大量来自生产 ...
2026-04-07Python凭借简洁的语法、丰富的生态库,成为算法开发、数据处理、机器学习等领域的首选语言。但受限于动态类型、解释性执行的特性 ...
2026-04-03在深度学习神经网络中,卷积操作是实现数据特征提取的核心引擎,更是让模型“看懂”数据、“解读”数据的关键所在。不同于传统机 ...
2026-04-03当数字化转型从企业的“战略口号”落地为“生存之战”,越来越多的企业意识到,转型的核心并非技术的堆砌,而是数据价值的深度挖 ...
2026-04-03在日常办公数据分析中,数据透视表凭借高效的汇总、分组功能,成为Excel、WPS等办公软件中最常用的数据分析工具之一。其中,“计 ...
2026-04-02在数字化交互的全场景中,用户的每一次操作都在生成动态的行为轨迹——电商用户的“浏览商品→点击详情→加入购物车”,内容APP ...
2026-04-02在数字化转型深度推进的今天,企业数据已成为驱动业务增长、构建核心竞争力的战略资产,而数据安全则是守护这份资产的“生命线” ...
2026-04-02在数据驱动决策的浪潮中,数据挖掘与数据分析是两个高频出现且极易被混淆的概念。有人将二者等同看待,认为“做数据分析就是做数 ...
2026-04-01