linux下可用/proc/self/status读取vmrss、vmsize和brk近似堆使用量,但vmrss含非堆内存,brk不包含mmap分配;windows需用getprocessmemoryinfo获取workingsetsize和privateusage;释放总量与碎片无法直接统计,须自行hook或使用malloc_info等诊断工具。

Linux下用/proc/self/status读取近似堆使用量
Linux不提供标准C++接口直接获取“堆分配总量”这类指标,malloc本身也不维护全局累计计数。最接近的方案是解析/proc/self/status中的VmRSS(实际物理内存驻留量)、VmSize(虚拟地址空间总大小),以及Heap相关字段(如MMAP_AREA、Brk等)。但要注意:VmRSS包含所有内存映射(包括共享库、mmap区域),不等于纯堆驻留;Brk只反映sbrk管理的heap segment,而现代glibc默认用mmap分配大块内存,这部分不会体现在Brk里。
实操建议:
- 用
std::ifstream("/proc/self/status")逐行扫描,匹配以VmRSS:、VmSize:、Brk:开头的行,提取数值(单位KB) - 不要依赖
Heap字段——它在较新内核中已被移除,glibc也不保证填充 -
VmRSS是唯一能粗略反映“当前驻留物理内存”的指标,但它含栈、数据段、共享库页等,不是纯堆
Windows下用GetProcessMemoryInfo查工作集与私有字节
Windows没有对应/proc的轻量级接口,必须调用PSAPI。关键函数是GetProcessMemoryInfo,返回PROCESS_MEMORY_COUNTERS_EX结构体。其中WorkingSetSize接近Linux的VmRSS(当前进程占用的物理页),PrivateUsage更接近“进程独占内存总量”,含堆、栈、私有数据段,但不含共享DLL的代码页。
实操建议:
- 需链接
psapi.lib,头文件包含<psapi.h></psapi.h> - 调用前确保结构体
cb字段设为sizeof(PROCESS_MEMORY_COUNTERS_EX),否则返回失败 -
PrivateUsage比WorkingSetSize更稳定,因后者受系统内存压力影响会波动;但它仍不是“堆分配总量”,只是进程私有内存上界
无法直接统计“释放总量”和“内存碎片”的根本原因
C++标准分配器(包括malloc、new)不记录每次free或delete的大小,glibc的ptmalloc2/mallocng也不对外暴露累计释放计数。所谓“内存碎片”是内部arena管理状态,没有统一定义:有的指mallinfo().fsmblks(空闲小块数),有的指malloc_info()输出中<small></small>和<large></large>的未合并空闲块,还有的用arena中system_mem - <code>uordblks估算碎片率——但这些全是启发式估算,且随分配模式剧烈变化。
实操建议:
- 若真需碎片监控,启用
malloc_info(0, fd)定期导出XML,解析<heap></heap>下的<total></total>与各<bin></bin>的size字段,计算空闲块占比 - 不要试图用
mallinfo()——它在glibc 2.33+已标记为deprecated,返回值语义模糊 - “释放总量”只能靠自行hook:重载
operator new/delete或LD_PRELOAD拦截malloc/free,自己累加;但会影响性能,且无法覆盖所有分配路径(如mmap直调)
调试阶段用malloc_stats()和malloc_info()快速看堆状态
glibc提供了两个诊断函数,适合开发期快速检查,但不适合生产环境高频调用(有锁、可能阻塞)。
实操建议:
-
malloc_stats()打印到stderr,含max system bytes(堆最大申请量)、in use bytes(当前已分配)、arena数量等,适合日志打点 -
malloc_info(0, fd)输出XML格式,可解析system_bytes(向OS申请总量)、inuse_bytes(用户持有量)、mmapped_bytes(mmap分配量),比malloc_stats()更细粒度 - 两者都要求程序链接时未定义
_GNU_SOURCE以外的宏,且不能在多线程高并发场景下频繁调用——内部会锁整个malloc arena
真正想拿到“堆分配总量”这种指标,必须从源头控制:要么全程用自定义分配器并计数,要么用LD_PRELOAD劫持所有分配/释放调用。操作系统提供的接口全是快照式、近似值,且混杂了非堆内存。碎片更没法精确定义——不同分配器对“碎片”的建模方式完全不同,强行统一统计反而误导判断。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











