vmhwm是进程自启动以来物理内存使用的峰值(单位kb),由内核维护且单调递增,仅在rss减少时更新,反映rss历史最高值而非当前占用。

Linux 下用 /proc/[pid]/status 读取进程物理内存峰值(VmHWM)
Linux 内核在 /proc/[pid]/status 中暴露了进程生命周期内的物理内存占用最高值,字段名为 VmHWM(Virtual memory High Water Mark),单位是 KB。它反映的是该进程自启动以来 RSS(Resident Set Size)达到过的最大值,即实际被加载进物理内存的峰值,不是当前值,也不是虚拟地址空间大小。
实操建议:
- 必须以目标进程的
pid替换路径中的占位符,例如读取 PID 1234 的峰值:cat /proc/1234/status | grep VmHWM -
VmHWM是只读快照,不会实时更新——它只在进程退出时最终确定;运行中多次读取可能返回相同值,不代表内存没波动,只是峰值未被打破 - 注意权限:非 root 用户只能读取自己启动的进程;监控其他用户进程需
sudo或cap_sys_ptrace能力 - 不要混淆
VmRSS(当前驻留内存)和VmHWM;前者随时变化,后者是历史最大值
Windows 上用 GetProcessMemoryInfo 获取 PeakWorkingSetSize
Windows 没有直接等价于 VmHWM 的内核字段,但 GetProcessMemoryInfo(来自 psapi.h)返回的 PROCESS_MEMORY_COUNTERS 结构体中,PeakWorkingSetSize 字段最接近物理内存占用峰值含义——它表示进程工作集(即当前映射到物理内存的页)曾达到的最大字节数。
实操建议:
- 调用前需用
OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid)获取句柄,且目标进程不能已退出 -
PeakWorkingSetSize单位是字节,不是 KB;注意与WorkingSetSize(当前值)区分 - 该值受系统内存压力影响:当系统内存紧张、发生工作集修剪(working set trimming)时,
PeakWorkingSetSize可能比实际分配过的物理页总数小——它只记录“被保留在工作集里”的峰值 - 若程序启用了
SetProcessWorkingSetSize主动收缩,PeakWorkingSetSize仍反映收缩前的历史高点,不受后续调用影响
C++ 跨平台封装要点:避免轮询误判和精度丢失
直接裸调系统接口容易出问题:比如在 Linux 上反复读 /proc/[pid]/status 并取最大值,其实毫无意义,因为 VmHWM 本身已是峰值;Windows 上若每秒调用一次 GetProcessMemoryInfo 再自己维护 max,反而掩盖了真正的峰值(它本就由系统维护)。
实操建议:
- Linux:只需在进程退出后(或你关心的监控周期结束时)读一次
VmHWM;运行中想看趋势?改用VmRSS+ 外部采样逻辑,但那不是“峰值” - Windows:每次调用
GetProcessMemoryInfo都能拿到当前已知的PeakWorkingSetSize,无需自己缓存;但要注意——如果进程已退出,句柄失效,无法再获取 - 单位统一:Linux 返回 KB,Windows 返回字节;C++ 封装时建议内部统一转为字节,对外暴露
uint64_t peak_physical_bytes()这类语义清晰的接口 - 别依赖
GetPerformanceInfo或GlobalMemoryStatusEx:它们返回的是全系统内存状态,和单个进程的物理内存峰值无关
为什么不用 mallinfo 或 malloc_stats?
这两个是 glibc 提供的堆内存统计接口,只反映 malloc/free 管理的用户态堆区情况,完全不包含 mmap 分配的大块内存、共享库代码段、线程栈、内核为进程维护的数据结构等。现代 C++ 程序大量使用 mmap(MAP_ANONYMOUS)、std::pmr::monotonic_buffer_resource 或直接 VirtualAlloc,这些都不会计入 mallinfo.uss 或类似字段。
常见错误现象:
- 程序实际物理内存峰值达 800MB,但
mallinfo().hblkhd显示仅 50MB——差的那 750MB 很可能来自大页分配或第三方库的私有内存池 -
malloc_stats()输出的 “max system bytes” 是 malloc 实现层的内部上限,并非 OS 层面的物理内存峰值 - 在 musl libc 或 Windows 上,
mallinfo根本不可用或行为不一致,跨平台封装时尤其危险
真正可靠的物理内存峰值,永远来自操作系统内核提供的进程级指标:Linux 的 VmHWM、Windows 的 PeakWorkingSetSize。其它任何用户态内存统计都只是子集,而且是容易过时或缺失关键路径的子集。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











