Linux 通过 /proc/self/status 的 VmHWM 字段、Windows 通过 GetProcessMemoryInfo 的 PeakWorkingSetSize 字段获取进程物理内存驻留集峰值,二者是跨平台唯一可信指标,其他方式如 mallinfo 均不可靠。

Linux 下用 /proc/self/status 读取 VmHWM
Linux 内核会在进程的 /proc/[pid]/status 文件中记录当前内存使用快照,其中 VmHWM(Virtual memory High Water Mark)字段就是该进程自启动以来达到过的最大物理内存驻留集(RSS)峰值,单位是 KB。这是最轻量、最可靠的方式,无需额外依赖或侵入式 hook。
实操建议:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
- 在关键路径前后(比如算法主循环开始前、结束后)调用一次读取函数,避免高频轮询影响性能
- 用
std::ifstream打开/proc/self/status,逐行扫描以VmHWM:开头的行,再用std::stoi提取数值 - 注意:该值反映的是内核统计的 RSS 峰值,不包含 swap 或 page cache,但对绝大多数内存泄漏/爆内存问题已足够敏感
- 若程序 fork 了子进程,
VmHWM是单个进程的值,不是整个进程组总和
Windows 下调用 GetProcessMemoryInfo 查 PeakWorkingSetSize
Windows 没有类似 /proc 的伪文件系统,得靠 Windows API。核心是 psapi.h 中的 GetProcessMemoryInfo,它填充的 PROCESS_MEMORY_COUNTERS 结构体里,PeakWorkingSetSize 字段就是进程生命周期内的最大工作集大小(字节),等价于 Linux 的 VmHWM。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 需链接
psapi.lib,且运行时依赖psapi.dll(WinXP+ 都自带) - 调用前用
GetCurrentProcess()获取句柄,结构体要初始化为 0,并显式设置cb成员为sizeof(PROCESS_MEMORY_COUNTERS),否则调用会失败 -
WorkingSetSize是当前值,PeakWorkingSetSize才是峰值——别看错字段名 - 该值受系统内存压力影响:若系统内存紧张,工作集可能被收缩,导致
PeakWorkingSetSize被重置为当前值(罕见但存在)
跨平台封装要注意的三个坑
写一个统一接口看似简单,实际容易栽在细节上:
- Linux 下
/proc/self/status可能因权限被挂载为noexec,nosuid,nodev,但读取不受影响;不过某些容器环境(如 rootless Podman)可能根本不可见该路径,此时应降级返回 0 并记录警告 - Windows 的
GetProcessMemoryInfo在低完整性级别进程(如 IE Protected Mode)中可能返回 0 或失败,需检查GetLastError()是否为ERROR_ACCESS_DENIED - 两次采样之间若发生
fork()(Linux)或CreateProcess()(Windows),子进程会继承父进程的峰值计数器初始值,但后续各自独立增长——所以不要在多进程场景下用单次采样代表整体
别用 mallinfo 或 malloc_stats 代替
有人想用 glibc 的 mallinfo() 或 malloc_stats() 来估算峰值,这很危险:
-
mallinfo().usmblks只统计 malloc 分配器管理的堆内存,不包括 mmap 分配的大块内存、静态数据段、线程栈、共享库代码段等 - 现代 libc(如 musl、glibc 2.34+)已将
mallinfo标记为废弃,返回值语义模糊,uordblks等字段在多线程下非原子,可能撕裂 -
malloc_stats()输出到 stderr,无法直接捕获,且格式无保证,解析风险高 - 真正需要的是 OS 层面的物理内存驻留峰值,不是用户态分配器的内部视图
真实场景里,VmHWM 和 PeakWorkingSetSize 是唯二值得信任的指标。其他方式要么覆盖不全,要么精度失控,要么跨平台行为不一致。尤其当程序用了 mmap(MAP_ANONYMOUS)、OpenMP、或第三方库(如 OpenCV 的内存池)时,仅看 malloc 统计会严重低估实际内存压力。

















