tracemalloc 是 python 标准库内置的轻量级内存追踪工具,可精准定位内存分配热点,支持实时统计、快照比对和行级分析,但不跟踪 c 扩展直接分配的内存。

想查 Python 程序里哪段代码吃掉了最多内存?tracemalloc 是标准库自带的轻量级内存追踪工具,不用装包、开销小、定位准,特别适合调试内存泄漏或优化高内存消耗场景。
开启和基础统计
tracemalloc 默认不启用,需手动启动。启动后它会记录所有由 Python 解释器分配的内存块(主要是 list、dict、str、class 实例等),但不跟踪 C 扩展直接 malloc 的内存(如 numpy 数组底层内存)。
- 调用 tracemalloc.start() 开始追踪(建议在程序最开头)
- 用 tracemalloc.get_traced_memory() 获取当前已分配 + 峰值内存(单位字节)
- tracemalloc.get_statistics('lineno') 按文件行号汇总内存分配热点
定位具体哪行代码分配最多内存
get_statistics 返回的是 Statistic 对象列表,每个对象包含 filename、lineno、size、count 等字段。常用做法是取前 10 条看“谁占得最多”:
import tracemalloc
<p>tracemalloc.start()</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/ai/1191" title="LogoAi"><img
src="https://img.php.cn/upload/ai_manual/001/431/639/68b7ae1e908fd289.png" alt="LogoAi" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/ai/1191" title="LogoAi">LogoAi</a>
<p>利用AI来设计你喜欢的Logo和品牌标志</p>
</div>
<a href="/ai/1191" title="LogoAi" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/00968c3c2c15" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">Python免费学习笔记(深入)</a>”;</p><h1>... 运行你的代码 ...</h1><p>current, peak = tracemalloc.get_traced_memory()
print(f"当前内存: {current / 1024 / 1024:.1f} MB, 峰值: {peak / 1024 / 1024:.1f} MB")</p><p>for stat in tracemalloc.get_statistics('lineno')[:5]:
print(stat)
输出类似:example.py:42: size=2.4 MiB, count=120, average=21 KiB —— 表示 example.py 第 42 行共分配了 2.4MB,调用了 120 次。
对比两个快照,看增量变化
如果想专注某一段逻辑(比如循环迭代、函数调用)的内存增长,可用快照比对:
- 调用 tracemalloc.take_snapshot() 获取当前内存状态
- 执行目标代码后,再 take 一个 snapshot
- 用 snapshot2.compare_to(snapshot1, 'lineno') 查差异(只显示新增/增长最多的行)
这对排查“越跑越慢、内存越来越高”的问题非常有效,能排除初始化阶段的干扰。
实用技巧和注意事项
- 开启 tracemalloc 有轻微性能开销(约 5–10%),生产环境慎用,开发/测试阶段足够轻量
- 默认只追踪 256 字节以上的分配;如需追踪更小对象,启动时加参数:tracemalloc.start(256)(数字为最小追踪字节数)
- 想限制内存追踪总量防止自身吃太多内存,可用 tracemalloc.start(256, max_nframe=3) 控制堆栈深度
- 注意:它不追踪未被 Python 引用的对象(比如已 del 但还没被 gc 回收的),也不反映 C 扩展(如 pandas、numpy 底层)的真实内存占用







