Linux下堆内存监控需三者结合:/proc/self/status提供VmRSS/VmSize等粗粒度驻留指标;mallinfo()返回glibc堆瞬时状态(如uordblks)但已弃用;累计分配量必须重载operator new/delete自行埋点,碎片化分析依赖malloc_info()的XML细粒度数据。

Linux下用/proc/self/status读取堆内存快照(最轻量)
Linux进程的堆内存统计不靠C++标准库,而是依赖内核暴露的/proc/self/status。它提供的是粗粒度但稳定可用的指标,比如VmRSS(当前驻留物理内存)、VmSize(虚拟地址空间总大小),而真正反映堆分配行为的是Heap段相关字段——但注意:/proc/self/status本身不直接输出“堆分配总量”,需结合mallinfo或malloc_stats补全。
实操建议:
-
VmRSS≈ 当前驻留量(含堆、栈、共享库等,非纯堆);想单看堆驻留,优先用mallinfo().uordblks -
VmSize包含所有映射(包括mmap分配),不能当“堆分配总量”用 - 读取频率不宜过高(每次open+read触发一次内核查询,有开销),建议采样间隔≥100ms
- 示例:用
std::ifstream("/proc/self/status")逐行解析,匹配^VmRSS:和^VmSize:行
用mallinfo()获取glibc堆分配/释放/碎片数据(仅限glibc)
mallinfo()返回struct mallinfo,字段含义易误解:比如arena是主分配区大小,uordblks是已分配字节数(≈当前堆驻留量),fordblks是空闲字节数(≈释放后未归还给OS的内存),smblks和hblks反映小块/大块分配行为,间接提示碎片化趋势。
关键点:
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
uordblks + fordblks≈ 当前堆总占用(含空闲但未归还的块),不是“分配总量”——累计分配量需自行计数 - 碎片化判断看
fordblks / (uordblks + fordblks)比值:>30% 且smblks == 0常意味着大量小块空闲但无法合并 - 该函数在glibc 2.33+已被标记为deprecated,但目前仍可用;替代方案是
malloc_info(0, fd)输出XML,解析更重但信息更全 - 调用
mallinfo()本身不加锁,多线程下结果可能不一致,建议在单线程环境或暂停分配时调用
如何追踪“分配总量”和“释放总量”(必须自行埋点)
C++标准不暴露全局分配计数器,operator new和operator delete重载是唯一可靠方式。别指望mallinfo或/proc提供累计值——它们只反映瞬时状态。
实操要点:
- 重载全局
::operator new和::operator delete,用原子变量累加size和size(注意delete传入的是原始指针,无法获知size,需配合自定义header或内存池管理) - 若用
std::allocator,需封装模板特化,否则容器分配不被统计 - 避免在重载函数里做耗时操作(如打印、锁争用),否则拖慢所有new/delete;推荐用
std::atomic无锁累加 - 注意placement new不调用重载,不会被计入;同样,
mmap系分配完全绕过malloc,需单独hookbrk/mmap系统调用(复杂度高,一般场景不必要)
碎片化趋势难量化?看malloc_info()的<small>和<large>分布
malloc_info(0, fd)输出XML,比mallinfo()细粒度得多。其中<small>节点统计各bin中空闲块数量与大小,<large>显示mmap分配的大块,<heap>列出每个arena的使用率。这才是观察碎片化的实际依据。
怎么用:
- 将
malloc_info()输出重定向到std::stringstream,用简易XML提取(如找<small>count="X"和<large>size="Y") - 持续采样,若
<small>count持续上升但<small>size总和变化不大,说明小空闲块增多 → 碎片化加剧 - 对比
<heap>nr_full(满页arena数)和nr_empty(空arena数):空arena多但uordblks不降,说明内存被钉住无法释放 - 注意:
malloc_info()会短暂加锁,频繁调用影响性能;生产环境建议每秒最多1次
真要实时监控堆行为,没有银弹——/proc给驻留概览,mallinfo给粗略快照,累计量必须自己记,碎片化得靠malloc_info的细节。三者缺一不可,且任何一项都得小心线程安全和性能代价。

















