windows 必须用 globalmemorystatusex 替代 globalmemorystatus,因其支持超 4gb 内存;linux 须安全解析 /proc/meminfo 的 memtotal 行;macos 应用 sysctlbyname("hw.memsize") 获取物理内存总量。

Windows 上必须用 GlobalMemoryStatusEx,Linux/macOS 只能读 /proc/meminfo 或 sysctl,没有跨平台标准 API —— 所有“一次写完、到处运行”的封装,底层都是条件编译加系统调用分发。
Windows:为什么 GlobalMemoryStatusEx 不能用 GlobalMemoryStatus 替代
GlobalMemoryStatus 返回的 dwTotalPhys 是 DWORD(32 位),最大只支持 4GB;物理内存超 4GB 时直接截断,数值完全错误。而 GlobalMemoryStatusEx 使用 ULARGE_INTEGER 存储 ullTotalPhys,能正确返回上百 GB 的内存总量。
实操要点:
- 必须链接
kernel32.lib(MSVC 默认包含,但 MinGW 需显式加-lkernel32) - 调用前要初始化
MEMORYSTATUSEX的dwLength字段,否则函数返回FALSE且GetLastError()为ERROR_INVALID_PARAMETER - 示例关键片段:
MEMORYSTATUSEX memInfo; memInfo.dwLength = sizeof(MEMORYSTATUSEX); GlobalMemoryStatusEx(&memInfo); uint64_t totalBytes = memInfo.ullTotalPhys;
Linux:读 /proc/meminfo 时别硬编码字段位置
/proc/meminfo 是文本文件,MemTotal: 行格式固定但空格数不一(例如 MemTotal: 16324580 kB),不能用 sscanf(line, "MemTotal: %ld", &kb) 这类靠空格跳过的写法 —— 某些内核版本会在冒号后加多个 tab 或混合空格。
安全做法:
- 逐行读取,用
strncmp(line, "MemTotal:", 9) == 0判断开头 - 跳过冒号后所有空白(
isspace()),再用strtoll()解析数字,避免atoi截断大数值 - 单位恒为
kB,需乘以 1024 得字节数;注意strtoll返回的是long long,别存进int或size_t(32 位系统上会溢出)
macOS:用 sysctl 获取 hw.memsize 最可靠
sysctlbyname("hw.memsize", &bytes, &len, nullptr, 0) 直接返回 uint64_t 字节数,无需解析字符串或单位换算。比读 mach_host_self() + host_statistics64() 简单得多,也比 NSProcessInfo(仅 Objective-C/Swift)更底层、更可控。
注意点:
- 必须包含
<sys></sys>,不是<sys></sys> -
len必须初始化为sizeof(bytes),否则调用失败返回 -1 - 该值是“物理内存总容量”,和 Linux 的
MemTotal语义一致(不含预留/不可用部分)
真正容易被忽略的是:不同系统对“物理内存总量”的定义其实有细微差别 —— Windows 的 ullTotalPhys 是 BIOS 报告的原始值,Linux 的 MemTotal 是内核实际可用的低端内存(已减去内核镜像、保留页等),macOS 的 hw.memsize 接近 BIOS 值但可能受 EFI 内存策略影响。如果做内存监控或资源预估,得先确认你到底需要“硬件标称值”还是“OS 实际可分配值”。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











