那个深夜,我的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学习杂记的其他文章
大模型:人工智能发展的引擎
我们经常看到大家在谈“大模型”,到底什么是大模型,大模型与小模型相比到底是哪里“大”。本文围绕这些问题简单介绍。
时间复杂度:一步步理解算法效率
在计算机科学中,时间复杂度是用来衡量算法效率的指标之一。它描述了在处理不同规模的数据时,算法需要花费的时间。
把py程序封装成可执行文件
程序封装指把程序脚本进行一些打包、解析、整合处理生成一个新的文件。封装以后,其他没有安装(python)的电脑也能运行该程序,也能实现该程序的结果。
一文搞懂什么是向量数据库:为什么RAG离不开它
你问AI;我昨天上传的合同里,甲方是谁来着?AI能准确回答。背后的技术流程是:...
一文了解8个Python库线性规划问题建模
Python有多个开源的运筹优化库,本文介绍使用多种求解器来求解线性规划问题。
加入社区微信群
与行业大咖零距离交流学习
PMO实践白皮书
白皮书上线
白皮书上线