Linux需用MemAvailable除以MemTotal计算可用内存百分比,内核3.14+才支持;Windows直接用GlobalMemoryStatusEx的dwMemoryLoad计算100减该值得出可用百分比,两者不可统一接口。

Linux下用/proc/meminfo读取可用内存百分比
Linux没有“当前可用物理内存百分比”的单一系统调用,必须自己算:用MemAvailable除以MemTotal。注意MemAvailable是内核3.14+才有的字段,老内核得退回到MemFree + Buffers + Cached - Shmem估算,但误差大、不推荐。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 打开
/proc/meminfo,逐行读取,匹配MemTotal:和MemAvailable:开头的行 - 用
std::stoll()解析数值(单位是kB),避免atoi在超大内存下溢出 - 计算时转成double再除,否则整数除法结果恒为0:
static_cast<double>(available_kb) / total_kb * 100.0</double> - 若读不到
MemAvailable(如CentOS 6或旧内核),直接返回-1或抛异常,别硬凑MemFree——它不含可回收的page cache,会严重低估可用性
Windows下用GlobalMemoryStatusEx获取准确百分比
Windows API提供现成的MEMORYSTATUSEX结构体,其中dwMemoryLoad字段就是0–100的整数百分比,含义是“已用物理内存占比”,所以可用百分比 = 100 - dwMemoryLoad。这是最稳妥的方式,无需自己算。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 必须调用
GlobalMemoryStatusEx(&ms),不能用过时的GlobalMemoryStatus(不支持>4GB内存) - 调用前设
ms.dwLength = sizeof(ms),否则返回失败 -
dwMemoryLoad是近似值,但微软文档明确说它是“physical memory in use”,和任务管理器显示一致,可信 - 不需要管理员权限,普通进程可调用
C++跨平台封装时别硬写统一接口
Linux和Windows的内存模型差异本质是设计哲学不同:Linux暴露原始数据让你自己判断“可用”,Windows抽象出一个“已用负载”指标。强行用同一套逻辑(比如都去算available/total)会导致Windows端结果不准,因为GlobalMemoryStatusEx根本不提供available字段。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用
#ifdef _WIN32和#ifdef __linux__分条件编译,各自走原生路径 - 不要试图从Windows的
ullAvailPhys(可用字节数)反推百分比——它和dwMemoryLoad不严格互补,微软没承诺这种关系 - 如果需要定时轮询,Linux侧建议缓存
/proc/meminfo文件句柄并lseek(0)重读,避免反复open开销;Windows侧直接每次调用API即可
容易被当成“可用内存”但实际不是的几个坑
很多代码误把MemFree当可用内存,或把Cached全加进去,结果在数据库/Java服务跑满内存的机器上显示“还有40%可用”,其实根本分配不出新页——因为那些cache正被内核用于加速IO,且无法立即释放。
关键点:
-
MemAvailable是内核估算的“现在就能立刻分配给新进程的内存”,含可回收slab、page cache等,是唯一靠谱指标 - Windows的
dwMemoryLoad对应的是Physical Memory\% Usage性能计数器,和任务管理器一致,别自己另算 - 容器环境(Docker/K8s)下
/proc/meminfo反映的是宿主机值,若需容器限制内可用率,得读/sys/fs/cgroup/memory/memory.usage_in_bytes和memory.limit_in_bytes
真实场景里,MemAvailable可能比MemFree高几倍,也可能只高一点点——取决于当前page cache压力和内核回收策略。拿不准时,就信它。


















