Windows 通过 GetPerformanceInfo 的 CommitLimit 减物理内存估算页面文件大小,Linux 读 /proc/meminfo 的 SwapTotal 获取 swap 总量,二者语义不同且无统一跨平台 API。

Windows 下用 GetPerformanceInfo 获取页面文件大小
Windows 系统没有直接暴露“页面文件大小”的 API,但 GetPerformanceInfo 返回的 PERFORMANCE_INFORMATION 结构体里包含 CommitTotal 和 CommitLimit,它们分别代表当前已提交内存总量和系统允许的最大提交量(即物理内存 + 页面文件总容量)。页面文件大小 ≈ CommitLimit - 物理内存大小。
注意:CommitLimit 是硬上限,但页面文件实际大小可能因自动管理而浮动;该方法得到的是理论最大值,不是磁盘上 .sys 文件的精确字节。
实操要点:
- 需链接
Psapi.lib,头文件为<psapi.h> - 调用前确保进程有
SE_PROF_SINGLE_PROCESS权限(通常默认具备) -
dwPhysicalMemory字段在旧版 Windows(如 XP)中不可用,应改用GlobalMemoryStatusEx获取物理内存 - 返回值为
BOOL,失败时调用GetLastError()查错,常见为ERROR_INSUFFICIENT_BUFFER(但此函数不使用缓冲区,一般意味着权限或结构体尺寸不匹配)
Linux 下读取 /proc/meminfo 中的 SwapTotal
Linux 不叫“页面文件”而叫 swap,其总大小由内核通过 /proc/meminfo 暴露。关键字段是 SwapTotal:,单位为 kB。
立即学习“C++免费学习笔记(深入)”;
这个值反映所有激活 swap 分区/文件的总大小,不含未启用的 swap 设备。如果系统禁用了 swap,SwapTotal 为 0。
实操建议:
- 用
std::ifstream或 C 的fopen("/proc/meminfo", "r")逐行扫描,匹配以"SwapTotal:"开头的行 - 跳过前导空格后解析数字,注意它后面可能跟
kB或无单位(取决于内核版本),稳妥做法是读到第一个非数字字符就停 - 不要依赖
sysconf(_SC_PAGESIZE)或getpagesize()——那是内存页大小,和 swap 容量无关 - 该文件始终存在且无需特权,但若在容器中运行,可能被 cgroup 限制或挂载为只读,此时读取仍成功但值可能为 0
跨平台封装要注意的兼容性陷阱
没有标准 C++ 接口能统一获取页面文件/swap 大小,强行抽象容易掩盖差异。比如:
- Windows 的
CommitLimit包含物理内存,Linux 的SwapTotal是纯磁盘交换区,二者语义不同 - macOS 使用压缩内存 + swap(位于
/private/var/vm/swapfile*),但无单一总值 API;必须遍历 swapfile 并stat()求和,且需 root 权限才能访问部分文件 - 某些嵌入式 Linux 或 musl 环境可能禁用
/proc,此时该路径根本不存在 - 返回类型建议统一用
uint64_t(字节),避免size_t在 32 位系统上溢出(16GB+ swap 很常见)
为什么不用 GetSystemInfo 或 sysconf
GetSystemInfo 返回的是页面大小(dwPageSize)、地址空间范围等,和页面文件容量完全无关;sysconf(_SC_PAGESIZE) 同理,它只告诉你 malloc 分配的最小粒度,不是磁盘上 swap 的大小。
混淆这两者是初学者最常踩的坑:看到 “page” 就以为和 “paging file” 有关,其实一个是内存管理单元(MMU)概念,一个是虚拟内存后备存储概念。
验证方式很简单:
- Windows:任务管理器 → 性能 → 打开资源监视器 → 内存页签,对比 “提交限制” 和 “物理内存” 差值,再与磁盘上
pagefile.sys属性大小比对 - Linux:
free -h输出的Swap行第一列,应与cat /proc/meminfo | grep SwapTotal一致
真正需要页面文件大小的场景(比如内存敏感型服务做容量预估),绕不开操作系统特定接口——接受这点,比强求跨平台抽象更可靠。


















