Linux下用mallinfo或malloc_stats可获取堆分配总量(arena+hblkhd)和用户数据占用量(uordblks),但二者均不反映真实驻留内存(RSS),也不统计mmap分配;真正驻留量应读取/proc/self/status中的VmRSS字段。

Linux 下用 mallinfo 或 malloc_stats 看堆分配总量,但注意它不反映驻留内存
mallinfo 是 glibc 提供的接口,返回一个 struct mallinfo,其中 arena + hblkhd 近似当前向系统申请的总堆内存(即“分配总量”),uordblks 是已分配未释放的用户数据块字节数(常被误当作“驻留量”,实际不是)。但它不区分物理页是否被换出、是否被内核回收,也不统计 mmap 分配的内存(如大对象走 mmap 时就完全不计入)。调用前无需初始化,但结果是快照,且多线程下无原子保证。
更轻量的调试方式是调用 malloc_stats(),它直接打印到 stderr,包含 system bytes(向系统申请总量)和 in use bytes(当前用户占用),适合快速验证。但无法编程读取,仅用于诊断。
示例片段:
#include <malloc.h> #include <iostream> struct mallinfo mi = mallinfo(); std::cout << "total allocated: " << mi.arena + mi.hblkhd << "\n"; std::cout << "in-use user data: " << mi.uordblks << "\n";
/proc/self/statm 和 /proc/self/status 能查驻留内存(RSS)与虚拟内存(VSZ)
Linux 进程的真正驻留物理内存(RSS)必须查 /proc/self/statm —— 第二个字段是 RSS 页数,乘以 getpagesize() 得字节数;第一个字段是总虚拟内存页数(VSZ)。它反映的是内核视角的物理页占用,含代码段、堆、栈、共享库等所有驻留页,不单是堆。
立即学习“C++免费学习笔记(深入)”;
/proc/self/status 更易读:VmRSS: 行是 RSS 字节数,VmSize: 是 VSZ,VmData: 接近堆+数据段的粗略估计(但含 BSS、brk 扩展部分,不含 mmap 堆)。注意:这些值有延迟,内核不会实时更新,且受内存压缩、THP、swap 等影响。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
读取要点:
- 需用
std::ifstream或fopen打开/proc/self/status,逐行扫描匹配VmRSS: - 避免频繁读取(/proc 是伪文件系统,但仍有开销),生产环境建议采样间隔 ≥100ms
- 容器中若挂载了
procfs的子集,可能缺失字段,需 fallback 到statm
要统计“释放次数”或“分配频次”,得自己 hook malloc/free,glibc 不提供内置计数器
glibc 没有暴露分配/释放调用次数的接口。想统计释放次数、平均分配大小、高频分配栈等,唯一可靠方式是 LD_PRELOAD hook 或使用 __malloc_hook 等(已废弃)或改用 malloc_usable_size 配合自定义分配器。
推荐做法:在程序启动时用 malloc_hook 替换(仅限旧版 glibc),或更稳妥地用 LD_PRELOAD 注入一个包装 malloc/free 的共享库。关键点:
- hook 函数里必须用
__libc_malloc和__libc_free调用原函数,否则递归崩溃 - 计数器变量要用
static __thread或原子操作,避免多线程竞争 - 不要在 hook 里做 I/O 或锁重操作,否则严重拖慢内存路径
- C++ new/delete 默认调用 malloc/free,所以也会被覆盖;但
operator new(std::nothrow)或定位 new 不经过此路径
别混淆“堆分配总量”和“进程驻留内存”,它们由不同机制管理
堆分配总量(如 mallinfo.arena + hblkhd)只是 malloc 实现层向上申请的内存块累计值;而 RSS(/proc/self/statm 第二列)是内核维护的物理页映射总数。两者差异极大:malloc 释放后,内存常被保留在 arena 里供复用,RSS 不下降;大量小对象释放后若没触发 brk 回退或 madvise(MADV_DONTNEED),RSS 就一直虚高。
真正影响 OOM 的是 RSS,不是 malloc 统计值;监控告警应优先看 VmRSS,而不是自己累加 malloc 大小。另外,如果用了 jemalloc/tcmalloc,mallinfo 完全失效,必须用对应库的 API(如 malloc_stats_print)或 /proc。

















