vmsize(linux)和pagefileusage(windows)分别表示进程已提交的虚拟地址空间总量,前者单位kb、后者单位字节,均反映系统承诺可调度的地址空间上限,而非实际物理内存占用。

直接看 VmSize(Linux)或 PagefileUsage(Windows),别碰 VirtualSize 或 mmap 统计——前者是内核维护的虚拟地址空间总大小,后者才是真实提交到页文件/物理内存的量。
Linux 下读 /proc/self/status 的 VmSize 字段
VmSize 是内核在 /proc/self/status 中维护的当前进程虚拟地址空间总大小,单位是 kB,它包含所有已映射区域:堆、栈、共享库、mmap 区域(含 MAP_ANONYMOUS 和文件映射)、甚至 mmap(MAP_NORESERVE) 占用却未实际分配物理页的地址空间。
- 必须用
fopen("/proc/self/status", "r")+fgets()逐行读取,不能依赖字段顺序或硬编码行号 - 匹配时用
strncmp(line, "VmSize:", 7),跳过冒号后任意空白再调strtol(line + 7 + leading_spaces, nullptr, 10) - 别把 VmSize 当成“已用内存”——它不含 swap,也不反映物理页压力;它只是地址空间账本,可能远大于 RSS 或实际物理占用
- 该值在
open()时刻快照生成,两次读取间隔小于 1ms 也几乎不变,但解析字符串本身比读/proc/self/statm略重
Windows 下用 GetProcessMemoryInfo 取 PagefileUsage
GetProcessMemoryInfo 返回的 PROCESS_MEMORY_COUNTERS::PagefileUsage 字段,才是 Windows 上最接近 Linux VmSize 意义的指标:它表示进程当前已提交(committed)到页文件(pagefile)的虚拟内存总量,单位字节。
- 必须链接
psapi.lib,且项目中定义PSAPI_VERSION 1,否则旧版符号可能不解析 -
PagefileUsage不等于“已换出到磁盘的量”,而是“已向系统申请、可随时换入换出的虚拟内存上限”——哪怕全在 RAM 里,只要提交了就算 - 不要用
VirtualSize字段(该字段早已废弃,返回 0 或无意义值),也不要自己遍历VirtualQueryEx求和——开销大、结果不稳定、还漏掉某些内核映射区 - 调用前确保
pmc.cb = sizeof(pmc)已设,否则函数直接失败;句柄用GetCurrentProcess()最安全,无需额外权限
为什么不能靠 malloc/mmap 计数来估算虚拟内存
手动累加 malloc 返回大小或 mmap 长度,会严重失真:
-
malloc小块内存通常走sbrk或brk,但 glibc 会预分配大片内存池(arena),你 malloc(1) 可能背后已占几 MB 虚拟地址 -
mmap分配时若带MAP_NORESERVE,地址被划走但根本不进页表,PagefileUsage和VmSize都会计入,而你的计数器完全没反应 - C++
new可能触发直接mmap(尤其大对象),也可能走 malloc,行为取决于实现和大小阈值,不可预测 - 线程栈、VDSO、vvar/vdso 映射区、加载的共享库段,全都不经过你的分配器,但都算进
VmSize/PagefileUsage
跨平台封装时最容易忽略的细节
写一个 get_virtual_memory_bytes() 函数时,真正的坑不在 API 调用本身,而在单位、精度和语义对齐:
- Linux
VmSize是 kB,WindowsPagefileUsage是字节——别忘了乘 1024,否则数值差 1000 倍 - 两者都不是原子更新:
VmSize在open()时快照,PagefileUsage是调用瞬间采样,高并发下可能略滞后于真实状态 - 别在 tight loop 里每毫秒调一次:单次
GetProcessMemoryInfo或fopen+parse耗时约 5–20μs,但频繁调用会挤占 cache 和 syscall 资源,得不偿失 - 容器环境(如 Docker)中,
/proc/self/status仍有效,但PagefileUsage在 Windows 容器里行为一致;不过若程序跑在 WSL2,应优先走 Linux 路径而非试图调 Windows API
真正难的不是读哪个字段,而是理解 VmSize 和 PagefileUsage 都不是“已用虚拟内存”的精确计费器,而是操作系统视角下“已承诺可调度的地址空间总量”——它必然大于或等于 RSS / WorkingSetSize,但差多少,取决于你的内存访问模式和系统策略。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











