Python 内存泄露怎么能快速诊断?

我用 tornado 写了一个 API 服务器,但是貌似出现了内存泄露问题,内存一直在增长不释放,由于项目有点大,不可能用 memory_profile, 有什么办法可以可以发现到泄露点呢?


Python 内存泄露怎么能快速诊断?
3 回复

objgraphgc 模块,配合 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 内存

回到顶部