Linux下用/proc/self/status读取VmHWM可直接获取进程自启动以来RSS物理内存峰值(单位KB),需用std::ifstream逐行匹配“VmHWM:”后提取整数;Windows则须调用GetProcessMemoryInfo获取PeakWorkingSetSize(字节)。

Linux 下用 /proc/self/status 读取 VmHWM 最直接
Linux 内核会在进程的 /proc/[pid]/status 文件里实时记录内存使用快照,其中 VmHWM(Virtual memory High Water Mark)字段就是自进程启动以来达到过的最高物理内存驻留集(RSS)峰值,单位是 KB。这是最轻量、无需额外依赖的方式。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 在关键路径前后(比如算法主循环开始前、处理完一批数据后)调用一次读取函数,避免高频轮询影响性能
- 用
std::ifstream打开/proc/self/status,逐行扫描匹配以VmHWM:开头的行,再用std::stoi提取数值 - 注意:该值是内核维护的近似值,不包含 page cache、shared memory 等非独占内存,但对评估本进程实际 RSS 压力已足够可靠
- 示例片段:
int get_peak_rss_kb() { std::ifstream f("/proc/self/status"); std::string line; while (std::getline(f, line)) { if (line.rfind("VmHWM:", 0) == 0) { return std::stoi(line.substr(6)); } } return 0; }
Windows 上必须用 GetProcessMemoryInfo 查 PeakWorkingSetSize
Windows 没有等价于 VmHWM 的 proc 文件,得靠 PSAPI。核心是调用 GetProcessMemoryInfo 获取 PROCESS_MEMORY_COUNTERS 结构体,里面 PeakWorkingSetSize 字段才是对应“高水位”的字节数。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 链接时需加
-lpsapi(MSVC 下自动,MinGW 需显式指定) - 结构体字段名易混淆:
WorkingSetSize是当前值,PeakWorkingSetSize才是峰值,别看错 - 该值反映的是工作集(Working Set)峰值,即进程最近访问过、被保留在物理内存中的页,和 Linux 的
VmHWM语义最接近 - 注意权限:在某些沙箱或低完整性进程里可能返回 0 或失败,需检查
GetLastError()
跨平台封装要注意 VmHWM 和 PeakWorkingSetSize 的统计口径差异
两者都叫“峰值内存”,但底层统计逻辑不同:Linux 的 VmHWM 是 RSS 峰值(实际占用物理页),Windows 的 PeakWorkingSetSize 是工作集峰值(含预取、暂未换出的页)。同一程序在两系统上数值通常不一致,差 10%–30% 很常见。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 不要试图把两个值强行对齐或做减法比较;应分别记录、分别告警
- 如果要做自动化压测 baseline 对比,务必固定 OS + 内核版本,否则
VmHWM可能因内核内存管理策略更新而波动 - 避免在 fork 后子进程里读父进程的
/proc/self/status—— 子进程有自己的 pid 和 status 文件,/proc/self永远指向当前进程
别依赖 mallinfo 或 malloc_stats 查 HWM
mallinfo 返回的是 glibc malloc arena 内部统计,只覆盖堆分配器管理的内存,漏掉 mmap 分配的大块内存、C++ new 可能触发的直接 mmap、静态/全局变量、线程栈等。它的 usmblks 或 hblkhd 字段根本不是进程级峰值内存。
常见错误现象:
- 程序实际
VmHWM已到 1.2GB,mallinfo却只报 200MB —— 因为大量 buffer 走了mmap(MAP_ANONYMOUS) -
malloc_stats()输出到 stderr 的 summary 无法编程提取,且不含峰值信息 - 在 musl libc 或 Windows 上
mallinfo不可用,代码直接编译失败
真正需要进程级 HWM,就绕过 malloc 层,直查 OS 接口。越底层,越真实。
实际部署时最容易被忽略的是:监控点埋得太稀疏(比如只在程序退出前读一次),或者没考虑多线程竞争下峰值可能发生在任意时刻 —— 建议在资源密集型函数入口/出口、每处理 N 条记录后、以及 SIGUSR1 信号处理器里都留一个采样点。

















