tracemalloc 是 python 内置内存追踪工具,用于定位内存泄漏和高内存占用,需早期调用 start(),通过 take_snapshot() 和 compare_to() 定位分配源头,注意其不跟踪释放、小对象误判及 c 扩展盲区,生产环境宜按需轻量启用。

tracemalloc 是 Python 自带的内存追踪工具,专为定位内存泄漏和高内存占用问题设计,无需第三方依赖,适合在开发和测试阶段快速启用。
开启和基础使用
启动 tracemalloc 需在程序早期(如脚本开头)调用 start(),它会记录后续所有内存分配的调用栈:
import tracemalloc tracemalloc.start()
运行一段时间后,可通过 get_traced_memory() 获取当前已分配但未释放的内存(单位字节):
current, peak = tracemalloc.get_traced_memory()
print(f"当前内存: {current / 1024 / 1024:.2f} MB, 峰值: {peak / 1024 / 1024:.2f} MB")
获取内存分配源头(关键步骤)
调用 take_snapshot() 拍摄快照,再用 compare_to() 对比不同时间点的分配差异,精准定位“新增”或“持续增长”的内存来源:
立即学习“Python免费学习笔记(深入)”;
- 快照默认包含每行代码的分配次数和总字节数
- 推荐按
lineno排序(即具体文件+行号),而非仅按文件名 - 用
filter_traces()可排除标准库、虚拟环境路径等干扰项
示例:找出增长最多的前 10 行
snapshot1 = tracemalloc.take_snapshot() # ... 运行可疑代码 ... snapshot2 = tracemalloc.take_snapshot() <p>top_stats = snapshot2.compare_to(snapshot1, 'lineno') for stat in top_stats[:10]: print(stat)
常见误判与规避技巧
tracemalloc 不跟踪对象释放,只记录分配——这意味着:
- 频繁创建小对象(如循环中生成字符串、字典)会大量出现在 top 列表,未必是泄漏,需结合生命周期判断
- 被引用的对象不会被自动释放,即使原变量已删除;关注“谁还在持有引用”比“谁分配了它”更重要
- C 扩展(如 numpy 数组、PIL 图像)的部分内存可能不被 tracemalloc 捕获,需配合
psutil观察整体进程 RSS
建议搭配 gc.get_objects() 或 objgraph 进一步分析引用链。
生产环境轻量接入建议
tracemalloc 有性能开销(约 10%–30% 吞吐下降),不建议长期全量开启:
- 用环境变量控制开关:
if os.getenv("TRACE_MEMORY"):包裹 start() 和快照逻辑 - 限制追踪精度:调用
start(25)限制最大帧数,减少内存占用 - 定期采样:在 HTTP 请求钩子或任务完成时主动 take_snapshot(),而非持续运行
定位到可疑代码后,可临时加断点或日志验证对象是否被意外缓存。










