VmPeak是Linux进程自启动以来的最大虚拟内存值,单位KB,直接读取/proc/pid/status最准确高效;getrusage的ru_maxrss仅反映物理内存峰值且运行中基本为0;Windows无对应指标,需按需选用PEAK_PAGEFILE_USAGE等近似值。

Linux下读取/proc/pid/status里的VmPeak
进程最大虚拟内存(即峰值VIRT)在Linux中由内核维护,直接暴露在/proc/[pid]/status的VmPeak字段里,单位是KB。这是最准、开销最小的方式——不需要额外库,也不依赖采样间隔。
注意:VmPeak是自进程启动以来的历史最大值,不是当前值;它只在内核更新RSS/VmSize等指标时同步刷新,但基本可认为实时。
- 用
std::ifstream打开/proc/12345/status(把12345换成目标PID) - 逐行读取,匹配以
VmPeak:开头的行 - 用
std::stoi或strtol提取数值,别忘了跳过前导空格和单位kB - 如果文件不存在或权限不足(比如非root查其他用户进程),会读取失败——要检查
fail()或good()
用getrusage(RUSAGE_SELF)只能拿到当前RSS,不适用
getrusage(RUSAGE_SELF, &ru)返回的ru_maxrss字段在Linux上**实际是物理内存峰值(RSS)**,单位是KB,且glibc默认不更新该值为真实峰值——它只在进程退出时才写入最终值,运行中调用基本恒为0或极小值。很多文档没说清这点,导致误用。
- POSIX标准未规定
ru_maxrss是否实时,Linux实现选择延迟更新 - 即便启用
/proc/sys/kernel/ctrl-alt-del之类调试开关也无效 - 想监控虚拟内存峰值?必须绕过
getrusage,回到/proc路径
跨平台不可行,Windows需换方案
Windows没有/proc伪文件系统,VmPeak概念也不存在。对应的是GetProcessMemoryInfo返回的PEAK_PAGEFILE_USAGE(页文件峰值)或PEAK_WORKING_SET_SIZE(工作集峰值),但二者都不等价于Linux的VmPeak:
立即学习“C++免费学习笔记(深入)”;
-
PEAK_PAGEFILE_USAGE包含映射到页文件的私有提交内存,不含未提交的保留区(reserved but not committed) - 而Linux的
VmPeak包含所有mmap(MAP_ANONYMOUS)、sbrk、mmap(/dev/zero)等产生的虚拟地址空间,无论是否提交 - 所以Windows上无法1:1复现“最大虚拟内存”语义,只能按业务需求选最接近的指标
频繁轮询/proc会触发内核stat开销,别太激进
每秒读一次/proc/pid/status没问题,但若每毫秒读一次,可能引发明显性能抖动——每次读都触发内核遍历vma链表并累加,对大进程(如几十万vma)尤其明显。
- 实测:一个拥有约20万内存映射区的进程,单次
VmPeak读取耗时可达0.3ms(在较老内核上) - 建议采样间隔≥100ms;若需更高精度,考虑用eBPF在内核态聚合后用户态只读一次共享内存
- 别用
system("cat /proc/...")——fork+exec开销远大于直接open/read
真正难的不是读哪个字段,而是理解VmPeak反映的是“进程曾申请过的最大虚拟地址空间”,它可能远超实际物理内存消耗,也可能因mmap(MAP_NORESERVE)而完全不落地——监控时得清楚你到底想回答什么问题。


















