linux用/proc/self/status的vmhwm字段(kb)获取rss峰值,windows用getprocessmemoryinfo的peakworkingsetsize(字节),二者均反映物理内存压力峰值,非实时但单调递增;勿混淆vmpeak(虚拟内存峰值)。

Linux 下用 /proc/self/status 读取 VmHWM
Linux 内核会在 /proc/self/status 中记录当前进程的内存峰值(High Water Mark),对应字段是 VmHWM,单位是 KB。这是最直接、开销最小的方式。
注意:该值只在 Linux 上有效,且需进程有读取 /proc/self/status 的权限(通常都有);VmHWM 是自进程启动以来 RSS 的最大值,不是虚拟内存峰值(那是 VmPeak)。
实操建议:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 用
std::ifstream打开/proc/self/status,逐行读取直到匹配"VmHWM:" - 用
sscanf或std::stoi提取数字部分,别忘了跳过冒号和单位(如"VmHWM: 12345 kB") - 如果读取失败(比如容器环境挂载了精简版
/proc),应设默认值或 fallback 逻辑 - 该值更新有延迟,不是实时采样,但对“峰值”统计已足够
Windows 下调用 GetProcessMemoryInfo 获取 PeakWorkingSetSize
Windows 没有类似 /proc 的统一接口,必须用 PSAPI。关键函数是 GetProcessMemoryInfo,它填充的 PROCESS_MEMORY_COUNTERS 结构体里,PeakWorkingSetSize 字段即为工作集峰值(单位字节),最接近 Linux 的 VmHWM。
常见错误现象:链接时忘记加 psapi.lib,或未定义 PSAPI_VERSION=1 导致结构体偏移错乱。
实操建议:
- 包含头文件:
#include <windows.h></windows.h>和#include <psapi.h></psapi.h> - 调用前确保已加载
psapi.dll(推荐静态链接psapi.lib) - 初始化
PROCESS_MEMORY_COUNTERS pmc = {},避免未初始化字段干扰 -
PeakWorkingSetSize是工作集峰值,不等于堆分配峰值(如malloc累计最大值),也不含页面文件占用
跨平台封装时别混淆 VmHWM 和 VmPeak
Linux 的 /proc/self/status 同时提供多个峰值字段:VmHWM(RSS 峰值)、VmPeak(虚拟内存总大小峰值)、VmSize(当前虚拟内存大小)。很多人误把 VmPeak 当作“实际内存占用峰值”,但它包含所有 mmap 区域(包括未提交的、只读的、甚至 MAP_NORESERVE 的),数值常虚高数倍。
实操建议:
- 监控真实物理内存压力,只用
VmHWM(Linux)或PeakWorkingSetSize(Windows) - 避免在日志或指标中混用
VmPeak和VmHWM,二者语义完全不同 - macOS 没有等价接口,
task_info只能拿到当前phys_footprint,无历史峰值;若需跨三端,建议只在 Linux/Windows 实现,macOS 返回 -1 或抛异常
精度与时机:峰值不是调用时刻的瞬时值
无论 Linux 还是 Windows,这些峰值字段都是内核维护的单调递增计数器,只增不减。调用一次 API 得到的是“从启动到此刻为止的最大值”,不是当前占用。
这意味着:不能靠高频轮询来“抓峰值”,也不能假设两次调用间差值就是某段代码的内存开销——中间可能有其他模块触发了更高内存使用。
实操建议:
- 若要测量某段逻辑的内存增量,应在逻辑前后各取一次峰值,再相减(粗略估算)
- 注意子线程或异步操作可能影响全局峰值,无法隔离归因
- 某些极端场景(如
mmap(MAP_NORESERVE)+ 大量缺页)可能导致VmHWM滞后更新,但一般应用无需考虑
真正难的不是读哪个字段,而是理解你到底想监控什么:是物理内存压力(看 VmHWM/PeakWorkingSetSize),还是地址空间爆炸(看 VmPeak),抑或是堆分配行为(得 hook malloc)。选错指标,后面所有优化都跑偏。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










