Linux下通过读取/proc/self/status中的VmHWM字段(单位KB)可获取进程物理内存峰值,该值为RSS历史最高值、内核维护且单调递增;Windows调用GetProcessMemoryInfo获取PeakWorkingSetSize(字节);macOS无原生峰值接口,需自行采样phys_footprint并维护最大值。

Linux 下用 /proc/self/status 读取 VmHWM
Linux 系统中,当前进程的物理内存峰值(即驻留集大小的历史最高值)直接记录在 /proc/self/status 文件里,字段名为 VmHWM(单位是 KB)。这是最轻量、最可靠的方式,无需链接额外库或调用系统 API。
常见错误是误读 VmRSS(当前物理内存占用),它反映的是瞬时值,不是峰值。而 VmHWM 才是你要的“历史最大驻留集”。
- 用
std::ifstream打开/proc/self/status,逐行扫描以VmHWM:开头的行 - 注意字段后有空格和单位(
KB),需跳过空白并提取数值部分 - 该文件只在 Linux 上存在,macOS 或 Windows 下会失败,务必加平台判断
- 示例片段:
std::ifstream f("/proc/self/status");<br>std::string line;<br>while (std::getline(f, line)) {<br> if (line.rfind("VmHWM:", 0) == 0) {<br> size_t pos = line.find_first_of("0123456789");<br> if (pos != std::string::npos) {<br> long hwm_kb = std::stol(line.substr(pos));<br> return hwm_kb * 1024; // 转为字节<br> }<br> }<br>}
Windows 下调用 GetProcessMemoryInfo 获取 PeakWorkingSetSize
Windows 没有类似 /proc 的伪文件系统,必须用 Windows API。核心是 GetProcessMemoryInfo,它填充 PROCESS_MEMORY_COUNTERS 结构体,其中 PeakWorkingSetSize 字段即物理内存峰值(单位字节)。
容易踩的坑是忘记链接 psapi.lib,或者没包含 <windows.h> 和 <psapi.h>。另外,该函数返回值为 BOOL,需检查是否成功,失败时字段值无意义。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 先用
GetCurrentProcess()获取当前进程句柄 - 分配
PROCESS_MEMORY_COUNTERS实例,并设cb成员为sizeof(PROCESS_MEMORY_COUNTERS) - 调用
GetProcessMemoryInfo后,直接读pmc.PeakWorkingSetSize - 注意:该值是 Working Set 峰值,等价于物理内存峰值(不包含换出页),符合通常理解
跨平台封装时别忽略 macOS 的特殊性
macOS 没有 VmHWM,也不支持 GetProcessMemoryInfo。唯一可行路径是调用 task_info(mach API),读取 task_basic_info64_data_t 中的 phys_footprint ——但它只提供当前值,**没有历史峰值**。
这意味着:在 macOS 上,C++ 无法通过标准手段获取物理内存占用峰值。你只能退而求其次,定期采样 phys_footprint 并自己维护最大值,但这样有竞态和精度损失(采样间隔漏掉尖峰)。
- 必须显式链接
-framework CoreServices -framework IOKit -
task_info需要task_for_pid权限,沙盒应用默认被禁用,开发调试可用,发布版常失败 - 不要试图用
getrusage的ru_maxrss:它在 macOS 上单位是字节,但值始终为 0(系统未实现)
为什么不用 mallinfo 或 malloc_stats
这两个接口只反映堆内存(heap)的分配情况,完全不包含代码段、栈、共享库、mmap 映射页等——而物理内存峰值是整个进程工作集(Working Set)的总和。依赖它们会严重低估真实值,尤其对大量使用 mmap 或线程栈的应用。
-
mallinfo已被标记为废弃,glibc 2.33+ 默认不导出;malloc_stats输出到 stderr,不可靠解析 - 即使只关心堆,
mallinfo.uordblks是当前已分配字节数,不是峰值;也没有对应历史最大值字段 - 现代 C++ 程序大量使用
std::vector、std::string、智能指针,其底层可能混合 malloc/mmap,仅看堆毫无意义
实际部署时,Linux 和 Windows 路径都可稳定获取准确峰值,但 macOS 是硬伤——不是写法问题,是系统接口缺失。如果目标平台含 macOS,就得接受“无法精确获取”这个事实,或改用外部监控工具(如 vm_stat + 定时轮询)折中处理。

















