那个深夜,我的Python程序偷偷把内存吃光了
版权声明
我们非常重视原创文章,为尊重知识产权并避免潜在的版权问题,我们在此提供文章的摘要供您初步了解。如果您想要查阅更为详尽的内容,访问作者的公众号页面获取完整文章。
Python学习杂记
扫码关注公众号
扫码阅读
手机扫码阅读
文章主旨:通过剖析Python引用循环导致的内存泄漏问题,强调弱引用和手动断链是解决循环引用的关键,并提醒慎用__del__方法。
关键要点:
- Python引用计数管理内存时,引用循环(A引用B,B引用A)会导致计数无法归零,内存无法释放。
gc模块的标记-清除算法可处理循环引用,但若循环中存在定义了__del__方法的对象,gc会放弃回收,导致内存泄漏。- 打破循环的两种有效方案:使用
weakref弱引用(不增加计数),或手动断链(如close()方法中将引用置None)。 - 排查循环引用的工具:
gc.get_referrers()/gc.get_referents()、objgraph可视化引用图、tracemalloc追踪内存分配。 - gc调优建议:调整阈值、手动控制回收时机、禁用
__del__采用上下文管理器;free-threading模式下gc停顿可能更明显。
内容结构:
- 引言:通过凌晨监控告警引出Python内存占用异常,类比“两个灯互相供电”,点明主题是引用循环。
- 引用计数机制介绍:说明引用计数原理(
sys.getrefcount),指出其无法处理循环引用的缺陷。 - 循环引用示例:
Node类互相引用导致计数不归零,类比“两灯互供电”。 - gc模块机制:标记-清除算法与分代回收(阈值
(700,10,5)),手动触发gc.collect()。 - 真凶
__del__:详细分析连接池场景下Connection.__del__调用pool.return_connection导致gc不敢回收循环垃圾。 - 解决方案:弱引用(
weakref.ref)和手动断链(close()方法置None)。 - 排查工具:
gc.get_referrers、objgraph.show_backrefs、tracemalloc。 - gc调优:调整阈值、手动控制、禁用
__del__、free-threading对gc停顿的影响。 - 结尾:作者实际修复方案(改为
close()+弱引用),并养成习惯避免互相引用。
文章总结:本文以生动比喻和真实案例,系统讲解了Python引用循环的内存泄漏成因、排查方法和解决方案,建议开发者慎用__del__,善用弱引用和上下文管理器。
Python学习杂记
Python学习杂记
扫码关注公众号
还在用多套工具管项目?
一个平台搞定产品、项目、质量与效能,告别整合之苦,实现全流程闭环。
查看方案
Python学习杂记的其他文章
文心一言深度试用
文心一言是国产里现阶段比较热门的国产ai产品,今天多次使用,测试其基本的写作功能、作图功能、代码解读能力。
使用遗传算法求解非线性优化问题
我们在平时遇到的业务问题,很多目标函数、约束函数都是非线性的。本文介绍使用一个遗传算法包来解决这些复杂的模型求极值的问题。
一文搞懂什么是向量数据库:为什么RAG离不开它
你问AI;我昨天上传的合同里,甲方是谁来着?AI能准确回答。背后的技术流程是:...
分享一个上海交大人工智能班在github上的开源知识库
最近看到一个不错的开源机器学习、运筹学相关的知识库汇总项目,今天给大家分享一下这个项目。
使用Python第三方库高效处理时间数据
在之前的文章中,介绍了python使用自带的库来处理时间数据,本文介绍使用第三方库来处理时间数据。
加入社区微信群
与行业大咖零距离交流学习
PMO实践白皮书
白皮书上线
白皮书上线