valgrind检测内存泄漏需程序退出后查看“definitely lost”及对应stack trace,编译必须加-g且禁用优化,配合--track-origins=yes精准定位源头;/proc/pid/smaps中private_dirty持续增长、slabtop显示kmalloc缓存obj持续上涨、mtrace解析后出现“memory not freed”均为关键证据。

查不到具体记录,说明你还没让泄漏“显形”——内存泄漏本身不会自动生成日志,必须主动用工具捕获运行时行为或解析内核/用户态的跟踪数据。
valgrind 输出里找 definitely lost 行
这是 C/C++ 程序最直接的泄漏证据,但前提是程序已退出、且编译带 -g。输出中真正有用的不是 summary,而是每一块 definitely lost 后面紧跟着的 stack trace:
-
definitely lost行会标出字节数和分配次数,比如definitely lost: 1,024 bytes in 1 blocks - 紧接着的
at 0x...: malloc (in /usr/lib/...)是调用点,再往下几行的by 0x...: your_function (your_file.c:42)才是源头 - 如果没看到源码行号,说明没加
-g编译,或者LD_LIBRARY_PATH没指向调试版 libc - 别忽略
--track-origins=yes参数——它能帮你定位指针赋值丢失的位置,比只看 malloc 更准
/proc/PID/smaps 里看 Private_Dirty 增长趋势
/proc/PID/smaps 不是“记录”,但它是泄漏在物理内存上的真实投影。重点盯住 Private_Dirty 字段(即进程独占且被修改过的物理页),它比 RSS 更细粒度:
- 执行
grep -A 1 -B 1 "Private_Dirty" /proc/PID/smaps | grep -E "^[0-9]"提取数值,单位 KB - 配合
watch -n 5 'grep -A 1 -B 1 "Private_Dirty" /proc/PID/smaps | grep -E "^[0-9]"'每 5 秒刷新一次,观察是否单调上升 - 若某次业务操作后
Private_Dirty涨了 2MB 且不再回落,基本可锁定该操作路径下的分配未释放 - 注意:
Anonymous映射段的Private_Dirty高,大概率是堆泄漏;而libxxx.so段的高,则可能是全局缓存或静态对象累积
slabtop -s -a 看 kmalloc-* 缓存满载状态
内核态泄漏不记日志,但会在 slab 中留下“尸体”。slabtop -s -a 的输出里,真正要抓的是那些 USE 接近 100% 且 OBJ/SLAB 数持续上涨的缓存:
- 重点关注
kmalloc-128、kmalloc-256这类通用分配器缓存——它们被驱动、模块、文件系统大量使用 - 如果
ACTIVE和NUM OBJS都在涨,且sharedavail趋近于 0,说明 slab 已碎片化,新分配只能开新 slab,旧 slab 却无法回收 -
cat /proc/slabinfo | grep kmalloc-128查具体字段:num_slabs上涨 +sharedavail下降 = 典型泄漏特征 - 别只看
slabtop当前快照——它不保存历史,必须用watch -n 30 'slabtop -s -a | head -10'对比连续变化
mtrace 日志需手动解析,不能直接读
mtrace 生成的 MALLOC_TRACE 文件是纯文本,但不是人类可读的日志——它只记录地址和大小,没有上下文:
- 必须用
mtrace ./your_program ./mtrace.log解析,否则看到的只是类似@ 0x7f8fb5784000 0x100这样的原始记录 - 解析后输出里出现
Memory not freed:开头的块,才代表泄漏;每行末尾的./your_file.c:88是唯一可定位的线索 - 如果解析结果为空,常见原因是:没在
main()开头调用mtrace(),或程序异常退出(如 segfault)导致muntrace()未执行 -
mtrace只跟踪malloc/free,对mmap/MAP_ANONYMOUS或 C++new无效——这点容易误判
真正难的不是找到“记录”,而是确认哪条记录对应真实泄漏:用户态的 definitely lost 地址可能被 reuse,内核态的 kmalloc-128 满载可能是正常负载峰值。关键得交叉验证——比如 pmap -x PID 看匿名映射增长 + valgrind 报告位置一致,才能下结论。











