linux下通过/proc/self/status读取vmsize(当前虚拟内存总量)和vmpeak(历史峰值),单位kb,是最轻量可靠的统计方式;windows则用getprocessmemoryinfo获取peakpagefileusage(页文件占用峰值,单位字节)。

Linux下用/proc/self/status读取VMSize和VMPeak
Linux内核会在进程的/proc/self/status中实时记录虚拟内存使用情况,其中VMSize是当前虚拟地址空间大小,VMPeak是历史峰值(单位KB)。这是最轻量、最可靠的方式,无需额外依赖或权限。
注意:VMPeak只在进程生命周期内有效,子进程不会继承该值;且它反映的是mmap/vfork/brk等系统调用累计申请的虚拟地址空间总量,不等于物理内存占用。
- 用
std::ifstream打开/proc/self/status,逐行扫描以VMPeak:开头的行 - 解析后需跳过前导空格,用
std::stoi或strtol提取数值(字段末尾有KB单位) - 若读取失败(如容器环境挂载了简化
/proc),VMPeak行可能不存在,应设默认值或返回错误
Windows下通过GetProcessMemoryInfo获取PeakPagefileUsage
Windows没有直接对应VMPeak的指标,但PROCESS_MEMORY_COUNTERS_EX::PeakPagefileUsage最接近——它表示进程生命周期内页文件(pagefile)占用峰值,单位字节。这包含所有已提交(committed)的虚拟内存,包括私有提交页、映射文件的提交部分等。
这个值比Linux的VMPeak更“实在”(排除未提交的reserve),但也更保守(不包含仅reserve未commit的区域)。
- 需链接
psapi.lib,头文件包含<psapi.h></psapi.h> - 调用前确保启用
SE_DEBUG_NAME特权(仅调试时必要,普通进程通常可绕过) -
GetProcessMemoryInfo返回FALSE时检查GetLastError(),常见错误是ERROR_INVALID_HANDLE(句柄无效)或ERROR_ACCESS_DENIED(权限不足)
跨平台封装要注意size_t与单位一致性
不同系统返回的数值类型和单位不一致:Linux是KB字符串,Windows是字节SIZE_T。若封装统一接口,必须明确单位约定(推荐统一转为字节),否则容易在计算阈值或日志输出时出错。
- Linux路径
/proc/self/status在容器中可能被只读挂载或裁剪,建议加fallback逻辑(例如尝试/proc/[pid]/status并用getpid()拼接) - Windows的
PeakPagefileUsage在低内存压力下可能显著低于VMSize,不能简单当作“虚拟内存上限”来用 - 不要混淆
PeakWorkingSetSize(物理内存峰值)和PeakPagefileUsage,后者才是虚拟内存相关指标
为什么getrlimit(RLIMIT_AS)不是“虚拟内存限额”的可靠答案
RLIMIT_AS限制的是进程可分配的虚拟地址空间总量(address space),但它在现代Linux上常被设为RLIM_INFINITY,且即使设限,glibc的malloc也可能通过mmap绕过——比如大块分配直接走mmap(MAP_ANONYMOUS),不受sbrk类限制影响。
- 调用
getrlimit(RLIMIT_AS, &rlim)后,rlim.rlim_cur为软限,rlim.rlim_max为硬限;若两者都是RLIM_INFINITY,说明没设限 - 该限制对线程创建、共享库加载、栈增长也生效,但实际观测到的
VMPeak可能接近甚至略超软限(内核允许短暂超额) - 在容器环境中(如Docker),
cgroup v1 memory.limit_in_bytes或v2的memory.max才是真正的内存硬约束,但那是物理内存+swap,不是虚拟地址空间限额
VMPeak,后者在Windows看PeakPagefileUsage;而所谓“限额”,操作系统层面几乎没有严格 enforce 的虚拟内存上限,更多是资源配额或cgroup策略。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











