那个深夜,我的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学习杂记的其他文章
Python中处理Excel文件常用库介绍
Python中有许多常用的处理Excel的库,本文介绍几个经常使用的。
你的职场困境,根本不是努力的问题
最近收到一些留言,大同小异的主题:为什么我这么努力,却还是在职场里原地踏步?
WPS AI试用(与GPT、Claude参照对比)
金山办公的WPS AI已经开放申请了,申请网站https://ai.wps.cn/。大概一到两天就可以申请成功。
FittenCode,程序员必备的免费AI编程工具
Fitten Code 是由非十大模型驱动的AI编程助手,它可以自动生成代码,提升开发效率,协助调试 Bug。
SciPy工具包基本使用介绍
SciPy是科学计算工具库之一。它提供了很多最常用且最有效的算法和函数。傅里
加入社区微信群
与行业大咖零距离交流学习
PMO实践白皮书
白皮书上线
白皮书上线