memray 使用简介
Memray 是 Bloomberg 开源的 Python 内存分析器,其功能有:
- 追踪 malloc/free
- 定位内存泄漏、峰值内存、大对象分配
- 支持火焰图
- 实时监控、attach 到正在运行进程
- pytest 集成
- Jupyter 魔法命令
支持 Linux / macOS;Windows 支持有限;Python >=3.9
1. 安装
shell
pip install memray
# 或
python -m pip install memray
2. 核心流程总览
采集(run / attach)→ 生成 .bin 原始追踪文件 → 用子命令生成报告(flamegraph / table / tree / stats / summary / live)
.bin是memray的原始追踪文件,保存所有分配/释放栈信息- 同一个bin文件,可以反复生成多种不同报告
3. 采集:memray run(最常用)
shell
# 基础:直接跑脚本
memray run myscript.py
# 运行模块(等价 python -m xxx)
memray run -m mymodule
# 自定义输出文件名
memray run -o trace.bin myscript.py
默认输出文件名:memray-myscript.py.1234.bin(脚本名+pid)
run 高频参数
shell
--native 追踪C/C++/numpy等native库的调用栈(非常重要!分析numpy、torch必开,开销变大)
--live 实时终端监控,不输出bin文件
--live-remote 远程实时监控(服务端等待客户端连接)
--follow-fork 跟踪fork出来的子进程(多进程服务必备)
--trace-python-allocators 跟踪Python解释器内部allocator,文件更大更慢
--quiet 减少日志
--native生成的bin文件必须在同一台机器上生成报告,依赖本机so符号表
attach 到已经在跑的进程(不用重启)
shell
memray attach <pid>
# 也可以attach并直接live查看
memray attach --live <pid>
适合线上正在跑的服务、长时间后台任务。
4. 报告子命令(基于 bin 文件分析)
以下提到的 trace.bin 一般是 memray run 命令的产物。
4.1 flamegraph 火焰图(最推荐,HTML交互式)
shell
memray flamegraph trace.bin
生成 memray-flamegraph-xxx.html,浏览器打开。
火焰图解读:
- 横向:内存大小;纵向:调用栈(父函数在上,子在下)
- 鼠标悬浮:看函数、分配大小、分配次数
- 快捷键:
t:total(本栈+子栈总分配,默认)o:own(函数自身直接分配,不含子调用)a:按分配次数排序
火焰图常用选项:
- 倒置火焰图:适合找"谁在分配内存",根节点是分配点
shell
memray flamegraph --inverted trace.bin
- 只看峰值内存快照(peak模式,很多时候比全量图清晰)
shell
memray flamegraph --peak trace.bin
4.2 table 表格报告(HTML,适合检索、筛选)
shell
memray table trace.bin
表格:线程ID、分配大小、分配次数、代码位置,支持搜索过滤,适合批量看热点位置
4.3 tree 终端树形视图(快速看栈,不用浏览器)
shell
memray tree trace.bin
终端打印调用树,按内存大小排序,适合服务器无浏览器环境快速排查。
4.4 stats 统计概览(终端)
shell
memray stats trace.bin
输出:总分配、峰值、分配大小直方图、top分配位置、allocator分布(malloc/calloc/realloc)
4.5 summary 精简汇总
shell
memray summary trace.bin
极简的top列表,适合快速看最大的几个内存占用点
4.6 live 实时监控(不需要bin文件)
两种用法:
- 启动脚本同时开启实时监控
shell
memray run --live myscript.py
- attach到已有进程实时看
shell
memray attach --live <pid>
终端动态刷新,类似htop,实时看内存上涨,适合观察内存随时间变化、缓慢泄漏。
5. 代码内 API(不用命令行,埋点在代码里)
适合只想分析某一段代码,而不是整个程序:
- 方式1:with上下文管理器
python
import memray
with memray.Tracer("trace.bin"):
# 要分析的代码块
data = [bytearray(1024*1024) for _ in range(1000)]
- 方式2:start/stop
python
import memray
tracer = memray.Tracer("trace.bin")
tracer.start()
# 业务代码
tracer.stop()
之后依然用 memray flamegraph trace.bin 生成报告。
6. pytest 集成(单元测试里做内存检测)
安装插件:
shell
pip install memray-pytest
运行:
shell
# 所有测试都追踪
pytest --memray
# 只看峰值,生成火焰图
pytest --memray --memray-flamegraph
适合写回归:防止新版本引入内存泄漏。
7. Jupyter Notebook 魔法命令
shell
%load_ext memray
%%memray_flamegraph
# 这里写要分析的cell代码
import numpy as np
arr = np.zeros((10000,10000))
直接在notebook内渲染火焰图,非常方便数据分析场景。
8. 典型排查思路(实操套路)
- 怀疑内存持续上涨:
memray run --live或者memray attach --live pid,先看实时走势 - 找到峰值大:
memray flamegraph --peak trace.bin,看峰值时刻的调用栈 - 分析numpy/torch底层C分配:采集时加上
--native - 多进程程序:
--follow-fork,否则子进程分配抓不到 - 优先看 own 内存:很多时候外层大循环只是调用者,真正分配在子函数,切换
o排序
9. 对比 & 注意事项
- 和
tracemalloc:tracemalloc是Python层,memray直接hook系统malloc,可以抓到C扩展(numpy、pytorch)的内存,这是最大优势 - 和 py-spy:py-spy 主打CPU采样;memray 专门做内存
- 开销:追踪会拖慢程序,线上不要长时间开启;bin文件可能很大,长任务慎用
- 不能追踪mmap、显存(CUDA显存抓不到!只能抓进程堆内存)
10. 常见命令速查表
shell
# 采集
memray run -o trace.bin --native --follow-fork app.py
# 火焰图(peak快照)
memray flamegraph --peak trace.bin
# 终端树形
memray tree trace.bin
# 实时监控
memray run --live app.py
# attach 线上进程
memray attach --live <pid>
(END)