如何高效 debug Python 内存泄漏的问题

最近写了一个爬虫,循环下载 excel 表然后插入到数据库里面。

然后就出现内存泄漏的情况。

用 memory_prorfile 检查,定位了内存增长的代码段,但是怎么看都找不到泄漏的地方。

用 objgraph 检查,发现给出的信息很模糊,加上自己第一次用,也不知道怎么玩。

又达人指点下 python debug 内存泄漏的技巧么?

bow


如何高效 debug Python 内存泄漏的问题
2 回复

对于Python内存泄漏,我一般用这几个方法,按顺序来效率最高。

先上最直接的代码,用tracemalloc定位泄漏点:

import tracemalloc
import gc

def find_memory_leak():
    tracemalloc.start()
    
    # 你的业务代码
    your_function_that_might_leak()
    
    snapshot = tracemalloc.take_snapshot()
    top_stats = snapshot.statistics('lineno')
    
    print("[Top 10 memory allocations]")
    for stat in top_stats[:10]:
        print(stat)
    
    # 对比两次快照找增量
    snapshot2 = tracemalloc.take_snapshot()
    stats = snapshot2.compare_to(snapshot, 'lineno')
    
    print("\n[Memory growth]")
    for stat in stats[:10]:
        print(stat)

# 或者用objgraph看对象引用
import objgraph

def show_object_references():
    # 显示增长最快的对象类型
    objgraph.show_growth(limit=10)
    
    # 生成引用图(需要graphviz)
    objgraph.show_backrefs(
        objgraph.by_type('YourLeakyClass')[:3],
        filename='backrefs.png'
    )

实际debug时,我习惯这么操作:

  1. 先用gc模块看基础情况
import gc
gc.collect()  # 手动触发回收
print(f"Objects: {len(gc.get_objects())}")
print(f"Garbage: {len(gc.garbage)}")
  1. pympler快速分析
from pympler import tracker
tr = tracker.SummaryTracker()
# ...运行代码...
tr.print_diff()  # 显示内存变化
  1. 如果是Web服务,用memory_profiler逐行分析
# 安装后
python -m memory_profiler your_script.py
  1. 常见泄漏点检查

    • 全局列表/字典不断append
    • 缓存没设上限
    • 循环引用(特别是自定义类)
    • C扩展模块没正确释放
    • 线程/协程没正常退出
  2. 生产环境用filprofiler(支持Jupyter和脚本):

fil-profile run your_script.py

简单说就是:先用工具定位,再查常见坑。


python3 有 tracemalloc

回到顶部