最可靠的方式是直接读取/proc/meminfo解析memavailable和memtotal字段,计算公式为(memtotal−memavailable)/memtotal×100.0,memavailable比memfree更准确反映真实可用内存,需将kb转为字节后计算。

Linux 下用 /proc/meminfo 计算内存使用率最可靠
Linux 没有统一的“内存负载百分比”定义,系统监控工具(如 htop)通常基于 MemTotal 和 MemAvailable 推算。直接读取 /proc/meminfo 是最轻量、无依赖的做法,避免调用 sysinfo()(它返回的是总/空闲物理内存,不含 page cache 可回收部分,结果偏高)。
关键点:
-
MemAvailable是内核 3.14+ 引入的字段,代表当前可立即分配给新进程的内存(已扣除不可回收的 slab、page cache 中可回收部分等),比MemFree更真实 - 计算公式为:
(MemTotal - MemAvailable) / MemTotal * 100.0 - 需逐行解析,跳过注释和空行;字段名后带冒号和空格,注意
std::string::find(":")后的空白处理
std::ifstream meminfo("/proc/meminfo");
std::string line;
long long total = 0, available = 0;
while (std::getline(meminfo, line)) {
if (line.starts_with("MemTotal:")) {
total = std::stoll(line.substr(line.find(':') + 1)) * 1024; // kB → bytes
} else if (line.starts_with("MemAvailable:")) {
available = std::stoll(line.substr(line.find(':') + 1)) * 1024;
}
}
double usage_pct = (total > 0) ? (total - available) * 100.0 / total : 0.0;
Windows 下必须用 GlobalMemoryStatusEx(),GetPerformanceInfo() 不适用
Windows 的 GetPerformanceInfo() 返回的是系统启动以来的累计计数(如页面错误次数),和当前内存占用无关;真正可用的是 GlobalMemoryStatusEx(),它填充 MEMORYSTATUSEX 结构体,其中 dwMemoryLoad 字段就是系统声称的“内存使用百分比”(0–100)。
注意:
- 必须初始化
dwLength成员,否则调用失败返回 false -
dwMemoryLoad是估算值,基于ullTotalPhys - ullAvailPhys的比例,但会考虑 standby list 等 Windows 特有机制,和 Linux 的MemAvailable语义不完全对等 - 该 API 在 Windows XP SP2+ 可用,无需额外库,链接
kernel32.lib即可
MEMORYSTATUSEX memInfo;
memInfo.dwLength = sizeof(MEMORYSTATUSEX);
if (GlobalMemoryStatusEx(&memInfo)) {
int pct = memInfo.dwMemoryLoad; // 直接是 0–100 的整数
}
macOS 没有等价的单字段 API,得组合 host_statistics() 和 vm_statistics64
macOS 不提供类似 dwMemoryLoad 或 MemAvailable 的现成值。必须调用 host_statistics() 获取 vm_statistics64_data_t,再手动计算:可用内存 ≈ free_count + inactive_count(因为 inactive 页面在需要时可快速重用),再用 mem_size - available 算使用率。
容易出错的地方:
- 需包含
<mach></mach>和<mach></mach>,链接-framework CoreServices(实际只需-lmach) -
vm_statistics64_t中的计数单位是页(page),不是字节,必须乘以host_page_size -
inactive_count并非总是安全计入“可用”,极端情况下(如大量 dirty inactive)可能被排除,生产环境建议加保守系数(如只计 70% inactive)
host_t host = mach_host_self(); vm_size_t size = sizeof(vm_statistics64_data_t); vm_statistics64_data_t vm_stat; kern_return_t ret = host_statistics64(host, HOST_VM_INFO, (host_info64_t)&vm_stat, &size); uint64_t free_bytes = vm_stat.free_count * page_size; uint64_t inactive_bytes = vm_stat.inactive_count * page_size * 0.7; double usage_pct = (mem_size - free_bytes - inactive_bytes) * 100.0 / mem_size;
跨平台封装要注意字段缺失和精度陷阱
不同系统对“可用内存”的定义差异大:Linux 的 MemAvailable 包含可回收 cache,Windows 的 dwMemoryLoad 偏向保守,macOS 的 inactive 计算依赖策略。强行统一接口时,不要假设所有平台都返回相同精度或含义。
实操建议:
- Linux 下若内核 MemAvailable),退化为
(MemTotal - MemFree - Buffers - Cached),但结果会显著偏低(忽略可回收 slab) - 避免用浮点除法后四舍五入到整数再显示——用户看到 “99%” 和 “99.4%” 的心理感受不同,建议保留一位小数
- 频繁轮询(如每秒多次)时,Linux 下
/proc/meminfo是纯内存映射,开销极低;Windows/macOS 的系统调用有上下文切换成本,建议最小间隔 500ms
最常被忽略的是:没有检查 MemAvailable 是否真的存在,或 Windows 调用 GlobalMemoryStatusEx() 前忘了设 dwLength,导致返回 0% 或未定义值。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











