Windows用GlobalMemoryStatusEx获取ullAvailPhys/ullTotalPhys百分比,Linux读/proc/meminfo中MemAvailable与MemTotal计算百分比,macOS通过host_statistics64结合free_count与inactive_count及页大小估算可用内存百分比。

Windows 下用 GlobalMemoryStatusEx 获取可用物理内存百分比
Windows 提供的 GlobalMemoryStatusEx 是最直接、稳定的方式,它返回的是当前可用物理内存(包括 standby 和 free)占总物理内存的比例,符合“实际可用”的工程理解。
注意:不要用已废弃的 GlobalMemoryStatus,它不支持大于 4GB 的内存,且字段精度不足。
-
MEMORYSTATUSEX结构体必须先设置dwLength = sizeof(MEMORYSTATUSEX),否则调用失败返回 false -
ullAvailPhys是当前可用字节数,ullTotalPhys是总物理字节数;二者相除即得可用比例(需转 double 避免整数截断) - 结果不是“空闲内存占比”,而是系统认为可立即用于新进程的物理内存占比(含 standby list),更贴近真实可用性
MEMORYSTATUSEX memInfo;
memInfo.dwLength = sizeof(MEMORYSTATUSEX);
if (GlobalMemoryStatusEx(&memInfo)) {
double percent = (static_cast<double>(memInfo.ullAvailPhys) / memInfo.ullTotalPhys) * 100.0;
// percent 即当前可用物理内存百分比
}Linux 下读取 /proc/meminfo 计算 MemAvailable 百分比
Linux 从内核 3.14+ 开始在 /proc/meminfo 中提供 MemAvailable: 字段,它综合了 free、page cache 可回收部分、slab 可回收部分等,是目前最接近“用户态程序能实际申请到的物理内存”的指标。
别用 MemFree —— 它忽略大量可快速回收的缓存,结果严重偏低;也别自己算 MemFree + Buffers + Cached,这在新版内核中已不准确。
立即学习“C++免费学习笔记(深入)”;
将提醒同步至 Windows/Outlook 日历。用户提及「提醒我」「设置提醒」「加到日历」「同步到日历」「日程」「calendar」「日历」时触发。支持Microsoft Graph API 设备代码流认证,无需 Web 服务器,直接写入用户 Outlook 日历。
- 逐行读取
/proc/meminfo,匹配以MemAvailable:开头的行,提取其后的 kB 数值 - 同时读取
MemTotal:得到总内存 kB 数,二者相除得百分比 - 注意单位是 kB,不是 bytes;解析时跳过前导空格,用
strtoull或std::stoll更安全
// 示例关键逻辑(省略文件打开错误处理)
std::string line;
uint64_t memAvailable = 0, memTotal = 0;
std::ifstream f("/proc/meminfo");
while (std::getline(f, line)) {
if (line.rfind("MemAvailable:", 0) == 0) {
memAvailable = std::stoll(line.substr(13));
} else if (line.rfind("MemTotal:", 0) == 0) {
memTotal = std::stoll(line.substr(9));
}
}
double percent = (memTotal > 0) ? (static_cast<double>(memAvailable) / memTotal) * 100.0 : 0.0;macOS 下用 host_statistics 获取可用内存(需适配 Mach API)
macOS 没有直接等价于 MemAvailable 的字段,但可通过 host_statistics 调用 HOST_VM_INFO64 获取虚拟内存统计,其中 free_count 和 inactive_count 共同构成实际可用内存基础(inactive 页面可快速重用)。
注意:Apple 不保证 HOST_VM_INFO64 在所有 macOS 版本中字段顺序一致,必须用 vm_statistics64_t + sizeof 校验;且需要链接 -framework IOKit -framework CoreFoundation。
- 先调用
host_port = mach_host_self()获取 host port - 用
host_statistics64获取vm_statistics64_data_t,其中free_count是空闲页数,inactive_count是可回收页数(通常视为可用) - 页大小由
host_page_size给出,总物理内存需另行通过sysconf(_SC_PHYS_PAGES)和sysconf(_SC_PAGE_SIZE)计算
这个路径比 Linux/Windows 复杂,容易因结构体版本或权限问题失败;若仅需粗略估计,也可退而求其次读取 sysctlbyname("vm.stats.vm.v_free_count") 和 v_inactive_count,但不如 host_statistics64 完整。
跨平台封装时最容易被忽略的细节
写一个统一接口时,真正麻烦的不是调用本身,而是对“可用内存”的定义分歧和边界情况处理。
- Windows 的
ullAvailPhys包含 standby 内存,Linux 的MemAvailable包含可回收 page cache,macOS 的free_count + inactive_count是近似——三者语义接近但不完全等价,不能简单设为同一含义 - 当系统内存极度紧张(如
MemAvailable < 10MB),Linux 可能触发 OOM killer,此时返回值虽合法但已无实际参考价值 - 某些容器环境(如 Docker with memory limit)下,
/proc/meminfo显示的是宿主机总内存,而非容器 cgroup 限制值;需额外检查/sys/fs/cgroup/memory/memory.limit_in_bytes才能反映真实约束
如果目标是监控告警,建议各平台分别实现并保留原始字段;如果只是做 UI 状态指示,统一用百分比即可,但得接受不同系统间 ±5% 的合理偏差。

















