Linux下用/proc/meminfo读取MemAvailable与MemTotal计算可用内存百分比最可靠,MemAvailable反映真正可立即分配的内存(含可回收缓存),单位KB,需用double计算比例;老内核无该字段时退化为MemFree+Buffers+Cached-Shmem估算但误差大。

Linux下用/proc/meminfo算可用内存百分比最可靠
直接读/proc/meminfo是Linux上获取真实可用物理内存的唯一靠谱方式。别信free命令输出的available字段——它只是估算值,内核4.19+才引入,旧系统或容器里可能不准;更别用MemFree,它忽略page cache、slab等可回收内存,结果偏低20%~40%。
关键字段是MemAvailable(单位KB),配合MemTotal算百分比:percentage = (MemAvailable / MemTotal) * 100.0
- 每次读取都要重新打开并解析
/proc/meminfo,不能缓存文件句柄——内核会动态更新内容 - 注意换行符和空格:字段后有冒号+空格,比如
MemAvailable: 1234567 kB,需跳过冒号后所有空白再读数字 - 如果
MemAvailable不存在(如老内核),退化到用MemFree + Buffers + Cached - Shmem粗略估算,但误差大,建议加日志告警
Windows用GlobalMemoryStatusEx获取准确可用内存
Windows没有/proc这种接口,必须调GlobalMemoryStatusEx。它返回MEMORYSTATUSEX结构体,其中ullAvailPhys是真正可用物理内存字节数,ullTotalPhys是总物理内存,二者相除即得百分比。
- 必须用
dwLength = sizeof(MEMORYSTATUSEX)初始化结构体,否则调用失败返回FALSE -
ullAvailPhys已包含系统预留、硬件保留等不可用部分,比GlobalMemoryStatus(已废弃)准得多 - 该API线程安全,但频繁调用(如每100ms)会导致轻微性能开销,建议最低采样间隔设为500ms
C++跨平台封装时避免常见陷阱
写跨平台代码时,最容易踩的坑不是逻辑,而是数据类型和单位混淆。比如ullAvailPhys是ULONGLONG(64位无符号),而/proc/meminfo里数值是KB,不转成字节就直接除会得到错误百分比。
立即学习“C++免费学习笔记(深入)”;
- 统一用
uint64_t存内存值,Linux端读到KB后乘1024转字节,Windows端直接用字节值 - 不要用
std::stoull()解析/proc/meminfo——遇到空格或非数字字符会抛异常;改用strtoull(line.c_str() + colon_pos + 1, nullptr, 10) - 百分比计算用
double,但显示时四舍五入到小数点后一位就够了,再细没意义——内核统计本身就有1~2%抖动
动态走势采集要防抖和降频
单纯每秒读一次内存,画出来的曲线全是毛刺,看不出趋势。真实监控需要平滑+降频。
- 用环形缓冲区存最近30秒数据(比如每2秒采1次,共15个点),每次取平均值作为当前“有效值”
- 触发告警不要看瞬时值,而看连续5次采样都低于阈值(如10%),避免短时分配抖动误报
- 进程在cgroup限制下运行时(如Docker),
/proc/meminfo仍返回宿主机总量,必须额外读/sys/fs/cgroup/memory/memory.limit_in_bytes和memory.usage_in_bytes来算容器内可用率
实际部署时,最常被忽略的是容器环境下的内存指标错位——你以为在监控应用可用内存,其实一直在看宿主机的。这点不验证,所有走势图都是误导。


















