应使用memavailable/memtotal计算linux空闲内存比例,而非memfree/memtotal;windows需用globalmemorystatusex获取ullavailphys/ulltotalphys,且必须初始化memorystatusex.dwlength;跨平台时不可直接对比二者数值。

Linux下用/proc/meminfo读取空闲内存比例
Linux没有直接返回“空闲率”的系统调用,但/proc/meminfo提供了足够字段计算。关键不是看MemFree,而是MemAvailable——它才是内核估算的真正可立即分配的内存(含可回收的缓存),比MemFree更贴近实际可用性。
常见错误是只用MemFree / MemTotal,结果远低于真实可用值,尤其在缓存较多时会严重误判。
-
MemTotal:总物理内存(KB) -
MemAvailable:内核估算的可立即分配内存(KB),推荐用于空闲率计算 - 逐行解析
/proc/meminfo,匹配以这些字段开头的行,提取冒号后数字 - 注意单位统一为KB或字节,避免整型除法截断,用
double做除法
Windows用GlobalMemoryStatusEx获取内存使用率
Windows不暴露“空闲率”概念,而是提供ullAvailPhys(当前可用物理内存)和ullTotalPhys(总物理内存),两者相除即得空闲率。必须用GlobalMemoryStatusEx而非已废弃的GlobalMemoryStatus,否则在大于4GB内存的机器上会溢出。
容易忽略的是结构体初始化:MEMORYSTATUSEX的dwLength字段必须显式赋值,否则调用失败返回FALSE且GetLastError()为ERROR_INVALID_PARAMETER。
- 声明
MEMORYSTATUSEX msex;后,立即写msex.dwLength = sizeof(msex); - 调用返回
TRUE才可信,否则ullAvailPhys和ullTotalPhys无意义 - 结果建议保留2位小数,避免浮点精度误导(如99.999%显示为100%)
C++跨平台封装要注意的三个细节
不同系统字段语义不一致,硬套同一公式会出错。比如Linux的MemAvailable包含可回收页缓存,而Windows的ullAvailPhys不含页面文件,二者数值不可直接对比。
- 不要试图用宏定义统一接口名,先明确业务需求:是要告警阈值(如MemFree更安全),后者用
MemAvailable更友好 - Linux读
/proc/meminfo是文本IO,失败时检查errno是否为EACCES(容器环境可能无权限) - Windows下若程序以低完整性级别运行(如IE保护模式),
GlobalMemoryStatusEx可能返回0,需降级 fallback 到GetPhysicallyInstalledSystemMemory(仅总内存)+ 粗略估算
为什么free -h显示的“available”和你代码算的不一样
free命令的“available”列就是/proc/meminfo里的MemAvailable,但它的单位默认是KiB,而部分C++代码用std::stoi读取后直接当字节用,导致数值放大1024倍,空闲率算出来永远是0%。
另一个坑是free输出中“available”字段位置不固定(取决于列宽),不能靠空格分割第N列,必须按字段名精确匹配。
- 解析
/proc/meminfo时,用std::string::find("MemAvailable:")定位,再跳过冒号和空格提取数字 - 确认数字后是否有
kB字样(某些内核版本带单位),有则去掉 - 用
std::stoll而非std::stoi,防止32位系统上内存超2GB时溢出
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











