windows下getprocessmemoryinfo的pagefileusage字段准确反映进程已提交虚拟内存总量;linux无直接对应指标,/proc/self/statm的size仅表示虚拟地址空间大小;macos则缺乏等效接口,只能估算。

Windows下用GetProcessMemoryInfo获取VM提交量
在Windows上,GetProcessMemoryInfo 是唯一能直接拿到“已提交虚拟内存(Commit Size)”的系统API。它返回的 PROCESS_MEMORY_COUNTERS 结构里,PagefileUsage 字段就等于当前进程的提交量(单位字节),不是工作集也不是私有字节——这点常被误读。
-
PagefileUsage表示该进程当前占用的页面文件空间总量,等价于已提交但未映射物理页的那部分虚拟内存 + 已映射物理页的部分,即总提交量 - 必须链接
psapi.lib,头文件是<psapi.h></psapi.h> - 调用前需用
OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId())获取有效句柄,仅用GetCurrentProcess()不够(权限不足时GetProcessMemoryInfo会失败并返回0) - 如果返回
FALSE且GetLastError() == ERROR_ACCESS_DENIED,说明权限受限,常见于UAC启用时未以管理员运行,但其实对自身进程通常够用——关键看是否启用了低完整性级别(如浏览器沙箱)
Linux下通过/proc/self/statm和/proc/self/status解析
Linux没有直接对应“提交量”的字段,最接近的是 Size(/proc/self/statm 第一个值),单位为页,表示进程当前分配的全部虚拟内存大小(含未访问的mmap区域),但它不区分“已提交”和“仅保留”,严格来说是VMA总大小,而非Windows意义上的commit charge。
-
/proc/self/status中的VmSize:行(单位KB)与statm的Size×getpagesize()一致,可用作快速估算 - 真正反映内核实际承诺资源的是
VmPeak和VmHWM,但它们是历史峰值,非瞬时提交量 - 若需模拟Windows语义(即“内核已担保可分配的页数”),需结合
/proc/self/smaps中所有MMUPageSize区域的MMUPageSize×MMUPageCount求和——但代价高、无标准接口,生产环境不推荐 - 注意:ASLR、大页、THP等机制会让
statm的Size显著大于实际使用,尤其在大量mmap(MAP_NORESERVE)场景下,它完全不反映真实commit压力
跨平台封装时别混淆“提交量”和“驻留集”
很多开发者把 GetProcessMemoryInfo 的 WorkingSetSize 或 Linux 的 VmRSS 当成提交量,这是典型误解。前者是当前在物理内存中的页数,后者是常驻内存大小,两者都远小于提交量,尤其在稀疏分配或延迟分配场景下。
- 例如:malloc(1GB) 后未写入任何字节,在Linux上
VmRSS可能只有4KB,VmSize是1GB;在Windows上PagefileUsage约等于1GB,WorkingSetSize接近0 - 监控内存压力时,提交量(commit)决定OOM风险,驻留集(RSS/WorkingSet)只影响换页频率
- 第三方库如
libprocps或boost::process提供的内存接口大多只暴露RSS类指标,无法替代原生API获取提交量
macOS没有等效接口,只能估算
macOS内核不对外暴露进程级虚拟内存提交总量。task_info 返回的 tasks_basic_info_t 中 virtual_size 是地址空间总大小(类似Linux的VmSize),resident_size 是物理内存占用,二者之间没有“已提交但未驻留”的中间态字段。
- 可通过
vm_stat查看系统级 commit limit 和 used,但无法分进程 - mach port方式调用
host_statistics能拿到全局HOST_VM_INFO64,其中pages_compressed和free_count可间接反映压力,仍无法定位到单个进程 - 实践中,macOS应用若需评估自身内存承诺,只能保守按
malloc+mmap的累计申请量自行追踪,无法获得内核确认的真实commit值
Windows的 PagefileUsage 是目前唯一明确、稳定、无需特权的提交量指标;Linux和macOS要么语义不等价,要么需权衡精度与开销。真要跨平台做内存水位告警,建议以Windows为准,其他平台用 VmSize / virtual_size 作为宽松上界,而不是假装它们数值可比。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











