Python内存分析器memray的简单介绍

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文件)

两种用法:

  1. 启动脚本同时开启实时监控
shell 复制代码
memray run --live myscript.py
  1. attach到已有进程实时看
shell 复制代码
memray attach --live <pid>

终端动态刷新,类似htop,实时看内存上涨,适合观察内存随时间变化、缓慢泄漏。

5. 代码内 API(不用命令行,埋点在代码里)

适合只想分析某一段代码,而不是整个程序:

  1. 方式1:with上下文管理器
python 复制代码
import memray

with memray.Tracer("trace.bin"):
    # 要分析的代码块
    data = [bytearray(1024*1024) for _ in range(1000)]
  1. 方式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. 典型排查思路(实操套路)

  1. 怀疑内存持续上涨:memray run --live 或者 memray attach --live pid,先看实时走势
  2. 找到峰值大:memray flamegraph --peak trace.bin,看峰值时刻的调用栈
  3. 分析numpy/torch底层C分配:采集时加上 --native
  4. 多进程程序:--follow-fork,否则子进程分配抓不到
  5. 优先看 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)

相关推荐
收纳过往1 小时前
数据库加索引的时机:慢查询日志说话
android·开发语言·数据库·python·低代码·rxjava
小鹿学程序1 小时前
市赛python学习
python
高洁011 小时前
知识图谱:结构化表达实体与关系的知识组织技术
人工智能·python·深度学习·机器学习·迁移学习
骊山道童2 小时前
第 1 周 LLM 原理与高效微调知识精讲手册
python
Metaphor6922 小时前
轻松使用 Python 将 RTF 转换为 Word(含批量转换与格式互转)
python·word·rtf
zh路西法2 小时前
【深入理解 LSTM】从时间反向传播(BPTT)到长时记忆:门控机制与实验验证
pytorch·python·rnn·gru·lstm·bptt
青少儿编程课堂2 小时前
蓝桥杯青少组 + 全国青少年信息素养大赛 + 电子学会图形化考级|校园推箱子大挑战解析
c++·python·算法·bfs·信息学竞赛
2601_966949652 小时前
Python 实战:如何统计五档盘口买卖盘总挂单量?附计算公式与代码
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
全栈陈序员3 小时前
【Python】基础语法入门(二十九)—— 正则表达式实战:文本处理利器
开发语言·人工智能·python·正则表达式