您的位置:首页 >C++如何获取当前进程的虚拟内存大小 _ 平台特定API调用方法【实战】
发布于2026-05-05 阅读(0)
扫一扫,手机访问
在Linux下,读取/proc/self/statm是获取虚拟内存大小最直接的方法。其第一列表示总虚拟内存页数,乘以sysconf(_SC_PAGESIZE)得到的字节数,就对应着top命令中的VIRT值。这个数值包含了代码、数据、栈、共享库以及所有mmap映射区域在内的全部虚拟地址空间。

想在Linux上获取进程的虚拟内存大小?最直接、最经典的路径就是解析/proc/self/statm这个伪文件。它的第一列,也就是size字段,直接给出了进程占用的总虚拟内存页数。你只需要将这个数字乘以系统的页大小,就能得到以字节为单位的VIRT值——没错,就是top或htop命令里VIRT那一列显示的数字。
听起来简单,但实操起来有几个细节必须把握:
立即学习“C++免费学习笔记(深入)”;
sysconf(_SC_PAGESIZE)来获取系统页大小,可别想当然地硬编码4096。要知道,在一些ARM或RISC-V架构的系统上,页大小可能不同。/proc/self/statm每行固定有7个由空格分隔的字段,第一列就是我们要的size。它统计的是整个程序映像的大小,囊括了代码段、数据段、堆栈、共享库以及所有通过mmap映射的区域。long page_size = sysconf(_SC_PAGESIZE); std::ifstream f(“/proc/self/statm”); long size_in_pages; f >> size_in_pages; size_t virt_bytes = static_cast(size_in_pages) * page_size;
到了macOS,事情就变得不一样了。这里没有/proc文件系统,必须通过Mach微内核的API来获取信息。核心在于调用task_info函数,并传入TASK_BASIC_INFO_64这个信息 fla vor。返回的结构体中,virtual_size字段就是我们需要的虚拟内存字节数(切记,不是resident_size)。
这个过程有几个关键点容易踩坑:
立即学习“C++免费学习笔记(深入)”;
和。链接时,通常需要-framework CoreServices。在实际操作中,尤其是使用Xcode时,显式添加-framework Foundation可以避免一些潜在的符号冲突。kern_return_tKERN_SUCCESS。常见的错误KERN_INVALID_ARGUMENT,很多时候是因为task_for_pid的权限被拒绝——这在macOS 10.15 (Catalina) 及之后的版本中尤为常见,系统默认会拒绝非root进程的调试权限。TASK_BASIC_INFO_64_COUNT宏作为count参数传入。如果误用了32位结构体的计数,在64位进程下会导致越界读取,引发不可预知的问题。struct task_basic_info_64 tinfo;
mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT;
kern_return_t kr = task_info(mach_task_self(), TASK_BASIC_INFO_64,
(task_info_t)&tinfo, &count);
if (kr == KERN_SUCCESS) {
size_t virt_bytes = tinfo.virtual_size;
}
Windows平台并没有一个与Linux VIRT完全对等的概念。最接近的指标是使用GetProcessMemoryInfo函数获取PROCESS_MEMORY_COUNTERS_EX结构体,其中的PagefileUsage成员。它表示进程当前承诺使用的页面文件空间总量,包含了已提交(committed)但可能尚未被使用的虚拟地址空间,其语义与top的VIRT大致相当。
在Windows上实现时,需要特别注意以下几点:
立即学习“C++免费学习笔记(深入)”;
PROCESS_MEMORY_COUNTERS_EX,因为基础的PROCESS_MEMORY_COUNTERS结构体不包含PagefileUsage字段。SE_DEBUG_NAME权限。对于查询自身进程信息的情况,通常可以跳过。但如果你的进程运行在沙盒或低完整性级别下,可能仍然需要调用OpenProcessToken和AdjustTokenPrivileges来调整权限。PagefileUsage的单位直接就是字节,无需转换。但必须清楚它的统计范围:它只包含已提交(COMMIT)的内存,而不包括那些仅保留(RESERVE)而未提交的地址空间(通过VirtualAlloc with MEM_RESERVE分配的部分)。这一点与Linux的/proc/self/statm不同,后者会统计保留区域。PROCESS_MEMORY_COUNTERS_EX pmc;
pmc.cb = sizeof(pmc);
if (GetProcessMemoryInfo(GetCurrentProcess(), (PPROCESS_MEMORY_COUNTERS)&pmc, sizeof(pmc))) {
size_t virt_bytes = pmc.PagefileUsage;
}
把各个平台的代码写出来只是第一步。当试图将它们封装成一个统一的跨平台接口时,才会遇到真正的挑战。表面上看只是“读取一个数字”,但底层语义的差异极易导致封装结果失真。以下是三个最容易被忽略的“断裂点”:
/proc/self/statm的size包含了所有mmap映射的区域(无论是匿名的还是共享的)。而Windows的PagefileUsage只计算已提交的部分。如果你的程序大量使用了mmap并设置了MAP_NORESERVE标志,那么在Linux和Windows上报告出来的“虚拟内存大小”可能会相差数GB之多。virtual_size虽然包含了所有的vm_map_entry,但会自动排除一些内核的私有映射,例如动态链接器共享缓存(dyld shared cache)的只读部分。实际测试中,同一个程序在macOS上报告的值可能比在Linux上低10到20MB。/proc/[pid]/maps或使用macOS的vmmap命令进行辅助分析。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8