Linux下可用mallinfo或malloc_stats快速查看堆使用概况,前者返回结构体(如uordblks为已分配字节数),后者直接打印到stderr;malloc_info可导出含各arena详情的XML;Windows需用_heapwalk遍历堆块。

Linux下用mallinfo或malloc_stats快速看堆使用概况
标准C++没有跨平台的堆统计接口,但glibc提供了mallinfo和malloc_stats两个实用函数,适合在Linux调试时快速抓取当前进程的堆分配快照。
注意:mallinfo返回结构体字段含义容易误解——比如uordblks是已分配但未释放的字节数(即“正在用”的堆),而fordblks才是空闲块总大小;arena字段是主分配区大小,不包含mmap分配的内存。
-
mallinfo适合程序内定期采样,但结构体在不同glibc版本中字段顺序/语义有微小差异,建议只用uordblks、fordblks、smblks等稳定字段 -
malloc_stats()直接打印到stderr,适合临时加日志,输出含top chunk size、mmap分配次数等,但无法捕获为字符串 - 二者都只反映当前线程的主分配区状态,多线程下无法体现其他线程私有arena的使用情况
用malloc_info导出XML格式的完整堆拓扑
malloc_info比mallinfo更全面,能输出每个arena(包括thread-specific ones)的详细chunk分布,且格式规范可解析。
调用方式简单:malloc_info(0, fd)把XML写入指定文件描述符;malloc_info(0, stderr)直接打印。输出包含<heap>、<malloc>、<system_total>等标签,清楚区分mmap vs brk分配、各arena的nr_chunks和size。
立即学习“C++免费学习笔记(深入)”;
- 必须用
libgcc链接(通常默认满足),否则链接时报undefined reference to 'malloc_info' - 输出中
size字段单位是字节,nr_chunks是该size档位的chunk数量,不是总chunk数 - XML无缩进、无换行,解析前建议先用
xmllint --format美化,或用Python的xml.etree.ElementTree直接加载
Windows上用_heapwalk遍历堆块(仅MSVC)
Windows CRT提供_heapwalk函数,可逐个访问堆中每个block,获取地址、大小、类型(free/used)、是否CRT管理等信息。
关键点:需先调用_heapchk()确认堆一致,再用_HEAPINFO结构体配合循环遍历;每次调用_heapwalk移动指针到下一block,返回_HEAPEND表示结束。
- 必须定义
_CRTDBG_MAP_ALLOC并链接libcmtd.lib(Debug版),否则_heapwalk返回_HEAPBADBEGIN - 它不统计mmap类分配(如
VirtualAlloc),只覆盖CRTmalloc系列分配的内存 - 遍历时不能修改堆(如调用
malloc/free),否则行为未定义
生成可视化统计图需要自己解析+绘图
没有现成API直接输出“详细统计图”,所有系统级接口只给原始数据。真正要画图,得先提取关键指标(如各size class的chunk数、arena间负载差异、长期增长趋势),再用Python/Matplotlib或Go/Gonum绘图。
- 从
malloc_infoXML里提取//heap/system_total/@size和//heap/heap/@size做时间序列,就能画出堆增长曲线 - 解析
mallinfo多次采样结果时,注意hblkhd(mmap分配总量)变化比uordblks更能反映大对象泄漏 - 生产环境慎用
malloc_info——它会短暂锁住所有arena,高并发下可能引发几十微秒停顿
实际调试时,多数问题靠mallinfo一眼看出异常增长就够了;真要深挖碎片或多线程分配热点,就得结合malloc_info + 自定义解析器,别指望一键出图。


















