Python内存泄漏定位核心是识别生命周期异常延长的对象,可用tracemalloc追踪分配源头、gc与objgraph检测循环引用及滞留、psutil监控RSS趋势,并排查全局容器累积、闭包引用、日志残留和第三方库误用等常见模式。

Python 中定位内存泄漏,核心是识别本该被回收的对象却持续驻留在内存中。关键不在于对象数量多,而在于对象生命周期异常延长,尤其是循环引用或意外全局引用导致的“滞留”。
用 tracemalloc 快速追踪内存分配源头
这是 Python 3.4+ 内置的轻量级工具,适合定位“谁在哪儿申请了大量内存”:
- 程序启动时调用
tracemalloc.start()(可加参数限制跟踪栈深度,如tracemalloc.start(25)) - 运行一段时间后,调用
snapshot1 = tracemalloc.take_snapshot();再过一段时间,取snapshot2 - 用
snapshot2.compare_to(snapshot1, 'lineno')找出新增内存最多的代码行 - 注意:它只跟踪 Python 堆内存分配(
malloc级别),不包含 C 扩展或底层释放延迟,但对大多数纯 Python 场景已足够精准
用 gc 和 objgraph 检查循环引用与对象滞留
CPython 的垃圾回收器(gc)能处理循环引用,但若对象有 __del__ 方法或被注册到弱引用回调中,可能被放入 gc.garbage 而不自动清理:
- 启用调试模式:
gc.set_debug(gc.DEBUG_LEAK),运行后看是否输出“uncollectable”对象信息 - 用
objgraph.show_most_common_types(limit=20)查看当前存活对象类型分布,对比不同时间点的变化 -
objgraph.show_growth()显示自上次调用以来增长最多的类型,特别适合发现缓慢累积的泄漏 - 对可疑类型(如自定义类实例),用
objgraph.find_backref_chain(obj, objgraph.is_proper_module, max_depth=10)追溯谁在持有它
监控长期运行进程的内存趋势
内存泄漏常在服务长时间运行后暴露,需结合外部观测:
立即学习“Python免费学习笔记(深入)”;
- 用
psutil.Process().memory_info().rss定期记录 RSS 内存,绘图观察是否单向爬升(排除缓存、预分配等正常波动) - 在关键逻辑前后手动触发
gc.collect()并检查len(gc.get_objects())或特定类实例数是否回落 - 对 Web 服务(如 Flask/FastAPI),可在健康接口中嵌入简易内存快照,方便线上抽样(注意权限与性能影响)
排查常见泄漏模式
很多“泄漏”其实源于编码习惯问题:










