linux下获取虚拟内存大小应读取/proc/self/statm首字段页数并乘以getpagesize(),对应vmsize(virt),包含代码、数据、栈、共享库及mmap等全部虚拟地址空间。

Linux 下用 /proc/self/statm 读取虚拟内存(VSIZE)
Linux 进程的虚拟内存大小(即 VmSize,单位 KB)最可靠、开销最小的方式是读取 /proc/self/statm。这个文件第一字段就是进程当前的总虚拟内存页数,乘以页面大小(通常是 4096)即可得到字节数。
-
/proc/self/statm每行固定 7 个字段,第一个是总内存页数(含代码、数据、堆、栈、映射等),直接对应cat /proc/pid/status中的VMSize - 注意:该值是“已分配但未必实际使用”的虚拟地址空间总量,不是 RSS,也不代表物理内存占用
- 示例代码片段:
std::ifstream f("/proc/self/statm"); size_t pages = 0; f >> pages; size_t vsize_bytes = pages * static_cast<size_t>(getpagesize());</size_t> - 不依赖第三方库,无系统调用开销,适合高频采样(如监控 loop)
macOS 下用 task_info() 获取 virtual_size
macOS 没有 /proc,必须用 Mach API。关键字段是 task_basic_info64_data_t.virtual_size,它对应的是 VM 区域总大小(即 vmmap -v 显示的 “Virtual Memory” 总和)。
- 需链接
-framework CoreServices和-framework IOKit(部分环境还需-framework MachO) - 调用前要先获取当前 task 的
mach_task_t:用mach_task_self() - 务必检查返回值:
task_info()失败时返回非零值,常见原因是权限不足或结构体 size 不匹配(一定要用task_basic_info64_count而非硬编码) - 示例关键行:
struct task_basic_info64 info; mach_msg_type_number_t count = TASK_BASIC_INFO64_COUNT; kern_return_t kr = task_info(mach_task_self(), TASK_BASIC_INFO64, (task_info_t)&info, &count); if (kr == KERN_SUCCESS) vsize_bytes = info.virtual_size;
Windows 下用 GetProcessMemoryInfo() 的 PagefileUsage 是近似替代
Windows 没有直接暴露“虚拟地址空间总大小”的 API。GetProcessMemoryInfo() 返回的 PROCESS_MEMORY_COUNTERS_EX.PagefileUsage 是最接近的字段——它表示进程当前承诺(commit)的虚拟内存总量(含已分配未访问的页),单位字节。
- 它不等于
VirtualAlloc所有保留区之和(因为保留区未 commit 时不计入),但比WorkingSetSize更贴近“虚拟内存占用”语义 - 必须用
PROCESS_MEMORY_COUNTERS_EX结构体,并调用GetProcessMemoryInfo()前确保cb字段设为sizeof(PROCESS_MEMORY_COUNTERS_EX),否则返回失败 - 需要
#include <psapi.h></psapi.h>并链接psapi.lib - 示例:
PROCESS_MEMORY_COUNTERS_EX pmc; pmc.cb = sizeof(pmc); if (GetProcessMemoryInfo(GetCurrentProcess(), (PPROCESS_MEMORY_COUNTERS)&pmc, sizeof(pmc))) { vsize_bytes = pmc.PagefileUsage; }
跨平台封装要注意的三个坑
写一个统一接口时,最容易出错的不是逻辑,而是平台差异带来的隐性行为不一致。
- Linux 的
/proc/self/statm第一字段是页数,但某些嵌入式内核(如 uclibc 环境)可能不提供该文件,需 fallback 到sysconf(_SC_PAGESIZE)+mallinfo()估算(不精确,仅作保底) - macOS 的
virtual_size包含所有映射(包括 dyld 共享缓存、__TEXT __DATA 等),而 Linuxstatm也包含 mmap 区域,二者语义基本对齐;但 Windows 的PagefileUsage不含未 commit 的保留区,数值通常偏小 - 所有平台下该值都可能在两次读取间剧烈变化(比如刚
mmap了 1GB 区域但尚未 touch),不要假设它稳定——若用于阈值告警,建议加滑动窗口平滑
虚拟内存大小本身是个瞬态指标,不同系统定义略有出入,拿来做资源限制或 OOM 预判时,务必结合 rss 或 working set 一起看。单看 VSIZE 容易误判。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











