Python 内存泄露怎么能快速诊断?
我用 tornado 写了一个 API 服务器,但是貌似出现了内存泄露问题,内存一直在增长不释放,由于项目有点大,不可能用 memory_profile, 有什么办法可以可以发现到泄露点呢?
Python 内存泄露怎么能快速诊断?
3 回复
用 objgraph 和 gc 模块,配合 tracemalloc 来定位。
1. 先用 tracemalloc 看内存增长在哪:
import tracemalloc
tracemalloc.start()
# ... 运行你的可疑代码 ...
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]: # 看前10个
print(stat)
2. 用 objgraph 找循环引用或堆积对象:
import objgraph
# 显示增长最快的对象类型
objgraph.show_growth(limit=10)
# 运行一段操作后再看
objgraph.show_growth(limit=10)
# 如果发现某个类实例过多,看谁引用它
objgraph.show_backrefs(objgraph.by_type('YourClass')[0], max_depth=10, filename='backrefs.png')
3. 用 gc 强制回收并检查:
import gc
gc.collect() # 手动触发回收
print(gc.garbage) # 如果有对象在 gc.garbage 里,说明有无法回收的循环引用(定义了 __del__ 时常见)
快速流程:
- 用
tracemalloc定位到文件名和行号。 - 用
objgraph.show_growth()确认是哪种对象在泄漏。 - 用
objgraph.show_backrefs()画引用图,看为什么没被释放。
总结: 先定位增长点,再画引用链。
其实大多数时候没啥好办法,因为一般你写不出能内存泄露的代码,这些问题基本都是第三方库导致的。粗暴的话就每隔一段时间或处理一定请求后自动重启进程,非要找找可以参考这篇 http://www.jianshu.com/p/2d06a1a01cc3
flask 写 web app,开发环境开启 debug,每个未捕获的异常会长 4M 内存

