pyhon:(垃圾回收机制)超详细——一次搞懂

简介: python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略

python采用的是引用计数机制为主,标记-清除分代收集两种机制为辅的策略


引用计数机制:

PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少

简单地说也就是:有新的引用计数增加,被删除就减少,该对象立即被回收,对象占用的内存空间将被释放。

引用计数机制的优点:


1.简单

2.实时性:一旦没有引用,内存就直接释放了。不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时。

引用计数机制的缺点:


1.需要额外的空间来维护引用计数

2.循环引用


分代回收:

分代回收是一种以空间换时间的操作方式,Python 将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,Python 将内存分为了 3“代”,分别为年轻代(第 0 代)、中年代(第 1 代)、老年代(第 2 代),他们对应的是 3 个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。


新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python 垃圾收集机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。


同时,分代回收是建立在标记清除技术基础之上。分代回收同样作为 Python 的辅助垃圾收集技术处理那些容器对象

垃圾回收


标记清除:

显然,可以包含其他对象引用的容器对象都有可能产生交叉引用问题,而标记清除算法就是为了解决交叉引用的问题的。


标记清除算法是一种基于对象可达性分析的回收算法,该算法分为两个步骤,分别是标记和清除。标记阶段,将所有活动对象进行标记,清除阶段将所有未进行标记的对象进行回收即可。那么现在的为问题变为了 GC 是如何判定哪些是活动对象的?


事实上 GC 会从根结点出发,与根结点直接相连或者间接相连的对象我们将其标记为活动对象(该对象可达),之后进行回收阶段,将未标记的对象(不可达对象)进行清除。前面所说的根结点可以是全局变量,也可以是调用栈。


标记清除算法主要用来处理一些容器对象,虽说该方法完全可以做到不误杀不遗漏,但 GC 时必须扫描整个堆内存,即使只有少量的非可达对象需要回收也需要扫描全部对象。这是一种巨大的性能浪费。


相关文章
|
8月前
|
存储 设计模式 Java
深入 Python 解释器源码,我终于搞明白了字符串驻留的原理!
深入 Python 解释器源码,我终于搞明白了字符串驻留的原理!
102 2
|
7月前
|
存储 调度 C++
【操作系统】进程与线程的区别及总结(非常非常重要,面试必考题,其它文章可以不看,但这篇文章最后的总结你必须要看,满满的全是干货......)
【操作系统】进程与线程的区别及总结(非常非常重要,面试必考题,其它文章可以不看,但这篇文章最后的总结你必须要看,满满的全是干货......)
223 1
|
8月前
|
Java 编译器
【Java开发指南 | 第十九篇】Java方法
【Java开发指南 | 第十九篇】Java方法
38 0
|
8月前
|
存储 分布式计算 运维
第五章 Python函数你知多少
第五章 Python函数你知多少
|
存储 C语言
换硬币C语言(超详细分析!包会)
换硬币C语言(超详细分析!包会)
180 1
换硬币C语言(超详细分析!包会)
|
8月前
|
存储 Java 程序员
初识JVM(简单易懂),解开JVM神秘的面纱
初识JVM(简单易懂),解开JVM神秘的面纱
59 0
|
Java 编译器
重温经典《Thinking in java》第四版之第五章 初始化与清理(二十八)
重温经典《Thinking in java》第四版之第五章 初始化与清理(二十八)
70 0
|
存储 Java
手把手教你认识下 JVM 的内存划分,再记不住就真的没办法了
Java 在运行时会将内存划分为若干个区域,粗略的可以将内存划分为堆区和栈区,堆区主要存储 Java 对象。栈区主要记录对象的引用地址。
手把手教你认识下 JVM 的内存划分,再记不住就真的没办法了
|
Web App开发 JavaScript 前端开发
B乎问题:通俗的解释下Vite能用来干嘛?是怎么回事?
最近在B乎看到了这么一个问题,能不能通俗地讲 Vite 到底是用来干嘛的,一开始觉得这个问题没什么意思,因为 Vite 这个话题有太多的人讲了。
B乎问题:通俗的解释下Vite能用来干嘛?是怎么回事?
|
Java API
本来想用“{{”秀一波,结果却导致了内存溢出!(下)
本来想用“{{”秀一波,结果却导致了内存溢出!
179 0
本来想用“{{”秀一波,结果却导致了内存溢出!(下)