Python 进阶
Python 协程实现原理
dict 和 set 实现原理
Python 线程安全
Python 抽象语法树(AST)
Python 日志输出
Python 扩展入门(一)
Python 程序执行原理
Python 垃圾回收
yield 生成器工作原理
django 源码分析:请求处理过程
dict 设计与实现
Python 性能分析原理
PyCodeObject
Python 弱引用
Python 性能分析原理(二)
Python 源码分析(一)
Python Annotated
Python 依赖注入
检查工具
Python MRO
Python 标记清除
PyFrameObject
Python 动态创建类
python freelist
python代码编译成pyc
Python mmap 内存映射文件
Python值得学习的内容
async Future 对象
asyncio loop的实现
asyncio.sleep 的实现
asyncio 原理
Python 代码加密
Python Token类型
Python 扩展入门(二)
Python 性能优化
本文档使用 MrDoc 发布
-
+
首页
Python 标记清除
### Python 垃圾回收的标记清除机制 1. 标记阶段(Mark) 垃圾回收器从根对象(如全局变量、当前栈帧中的局部变量、CPU寄存器等)开始,递归遍历所有可达的对象。 在遍历过程中,所有被访问到的对象都会被“标记”为“存活”。 没有被标记的对象被视为不可达,即垃圾。 2. 清除阶段(Sweep) 垃圾回收器遍历所有对象,对未被标记为存活的对象进行回收,释放其占用的内存。 清除后,所有对象的标记被重置,为下一次垃圾回收做准备。 ### 循环引用的问题 - 循环引用指的是一组对象相互引用,形成闭环,导致它们的引用计数都不为零; - Python 的引用计数机制无法回收这种循环引用的对象,因为它们的引用计数永远不会降到零; - 这时,标记清除机制就发挥作用了; ### Python 如何清除循环引用对象 Python 的垃圾回收器(gc模块)结合了引用计数和分代收集机制: 1. 引用计数:绝大部分对象通过引用计数立即回收; 2. 分代垃圾回收: - Python 将对象分为三代(0代、1代、2代); - 新创建的对象属于0代,经过多次垃圾回收仍未被回收的对象会晋升到更高代; - 分代回收器周期性扫描高代对象,使用标记清除算法检测不可达对象; 3. 处理循环引用: - 当分代垃圾回收器运行时,它会标记所有可达对象; - 对于不可达的循环引用对象,它们不会被标记为存活; - 然后清除这些不可达对象,成功回收循环引用占用的内存; ### Python 如何找到不可达对象的原理 1. 根集合(Root Set) 垃圾回收器首先确定一组“根对象”,这些对象是程序当前直接可访问的,通常包括: ``` - 全局变量 - 当前执行栈中的局部变量 - CPU寄存器中的引用 - 内置模块中的引用等 ``` 2. 遍历引用图 - `gc` 会维护一个对象跟踪列表(主要是针对容器对象,如列表、字典、类实例等),这是一个双向链表,保存了需要gc追踪的所有对象; > 只有容器对象(如列表、字典、自定义类实例等)才会被垃圾回收器(gc模块)跟踪,因为它们可能形成循环引用。一些简单的不可变对象(如整数、小字符串)不会被 gc 跟踪; - 从根集合开始,递归遍历所有被根对象直接或间接引用的对象; - 遍历过程中,所有访问到的对象都会被标记为“可达”; 3. 不可达对象 - 遍历结束后,所有没有被标记的对象即为“不可达”; - 这些对象无法通过任何根对象访问到,说明程序中没有任何地方再使用它们; 4. 清理不可达对象 - 不可达对象被垃圾回收器回收,释放内存; ### 总结 - 标记清除机制通过标记所有可达对象,清理无用对象,解决了引用计数无法回收循环引用的问题; - Python 的垃圾回收器结合引用计数和分代标记清除,实现了高效的内存管理; - 循环引用的对象最终会被分代回收器检测并清除;
gaojian
2025年6月13日 15:25
分享文档
收藏文档
上一篇
下一篇
微信扫一扫
复制链接
手机扫一扫进行分享
复制链接
关于 MrDoc
觅思文档MrDoc
是
州的先生
开发并开源的在线文档系统,其适合作为个人和小型团队的云笔记、文档和知识库管理工具。
如果觅思文档给你或你的团队带来了帮助,欢迎对作者进行一些打赏捐助,这将有力支持作者持续投入精力更新和维护觅思文档,感谢你的捐助!
>>>捐助鸣谢列表
微信
支付宝
QQ
PayPal
Markdown文件
分享
链接
类型
密码
更新密码