windows 通过 getprocessmemoryinfo 的 peakworkingsetsize 获取进程峰值物理内存,linux 通过 /proc/self/status 的 vmhwm 字段读取,二者单位均为 kb;跨平台封装需注意语义差异、权限配置及容器环境适配。

Windows 上用 GetProcessMemoryInfo 读取峰值工作集
Windows 没有直接暴露“物理内存占用峰值”的全局系统接口,但每个进程的物理内存使用峰值(即历史最大工作集大小)可通过 GetProcessMemoryInfo 获取,前提是你要监控的是**当前进程或有权限打开的其他进程**。
关键点在于 PROCESS_MEMORY_COUNTERS_EX 结构体里的 PeakWorkingSetSize 字段——它单位是字节,反映该进程自启动以来占用物理内存的最大值(不包含页面文件,纯 RAM)。
- 必须启用
SE_DEBUG_NAME权限才能打开其他进程句柄(否则OpenProcess失败或返回 0) - 调用前需用
sizeof(PROCESS_MEMORY_COUNTERS_EX)初始化结构体cb成员,否则旧版 Windows 可能返回错误数据 -
GetProcessMemoryInfo不是实时采样,而是返回内核维护的快照值,无性能开销
// 示例:获取当前进程峰值工作集
PROCESS_MEMORY_COUNTERS_EX pmc = {0};
pmc.cb = sizeof(pmc);
if (GetProcessMemoryInfo(GetCurrentProcess(), (PPROCESS_MEMORY_COUNTERS)&pmc, sizeof(pmc))) {
printf("Peak Working Set: %zu KB\n", pmc.PeakWorkingSetSize / 1024);
}
Linux 下读 /proc/[pid]/status 的 VmHWM 字段
Linux 用 VmHWM(High Water Mark)表示进程生命周期中驻留集(RSS)达到过的最高值,单位是 KB,对应物理内存峰值。它比 VmRSS 更可靠,后者只是当前值。
注意:/proc/[pid]/status 是每个进程私有路径,你必须有读取目标进程 proc 目录的权限(通常是同用户或 root)。非 root 用户无法读其他用户的 /proc/[pid]/。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
VmHWM值在进程退出后仍保留,直到被内核回收;但若进程长期运行,该值不会自动清零 - 不要误用
VmPeak(虚拟地址空间峰值),它和物理内存无关 - 某些容器环境(如 cgroups v2)下,
VmHWM可能被限制或失真,需结合memory.current和memory.peak判断
// 示例:读取当前进程 VmHWM
FILE* f = fopen("/proc/self/status", "r");
char line[256];
while (fgets(line, sizeof(line), f)) {
if (strncmp(line, "VmHWM:", 6) == 0) {
unsigned long hwm_kb;
sscanf(line, "VmHWM: %lu kB", &hwm_kb);
printf("VmHWM: %lu KB\n", hwm_kb);
break;
}
}
fclose(f);
跨平台封装要注意的三个硬伤
写一个“跨平台获取物理内存峰值”的 C++ 封装时,最容易翻车的地方不是 API 调用,而是语义错位和权限盲区。
- Windows 的
PeakWorkingSetSize包含共享页(如 DLL 代码段),而 Linux 的VmHWM默认按进程独占 RSS 计算,两者数值不可直接对比 - macOS 没有等价字段——
task_info只提供当前resident_size,Peak类字段需自己采样+维护,且无内核级保证 - 容器或沙箱环境下(Docker、Firejail、Flatpak),/proc 文件可能被挂载为只读或过滤,
GetProcessMemoryInfo可能返回 0 或失败,此时应降级为日志告警而非 crash
为什么不用 GlobalMemoryStatusEx 或 /proc/meminfo
这两个接口常被误用:它们返回的是**整个系统的物理内存状态**,不是某个进程的峰值。比如 GlobalMemoryStatusEx 的 ullTotalPhys/ullAvailPhys 是总量与空闲量,差值是当前已用总量,但无法拆解到进程粒度;/proc/meminfo 的 MemUsed 同理。
更关键的是,它们根本不记录“峰值”——系统级内存使用没有“历史最高”字段。想靠减法推导某进程峰值(比如“此刻总用量 − 无该进程时总用量”)在多进程并发场景下完全不可靠。
- 系统级接口不能替代进程级采样
- 所有声称“一行代码获取全系统内存峰值”的方案,本质上都是对概念的误解
- 真正需要进程级峰值,就必须走进程专属路径(Windows 的 PMI、Linux 的 /proc/[pid]/status)
实际部署时,最易被忽略的是权限初始化:Windows 下漏掉 AdjustTokenPrivileges 开启 SE_DEBUG_NAME,Linux 下没加 sudo 或没进目标用户 session,都会让读取静默失败——返回 0 或默认值,而不是报错。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










