linux下获取空闲内存最直接的方式是sysinfo(),其freeram字段需乘以页大小换算为kb;windows则必须用globalmemorystatusex()的ullavailphys字段,二者语义不同不可等同。

Linux 下用 sysinfo() 读取空闲内存最直接
Linux 系统里,sysinfo() 是最轻量、最可靠的方式获取当前空闲物理内存(单位是 KB)。它不依赖 procfs 解析,也不需要 root 权限,且调用开销极小。
注意:sysinfo() 返回的 freeram 字段是“可用空闲页帧数”,需乘以 sysconf(_SC_PAGESIZE) 才能换算成字节;但更常用的是直接用 KB(freeram * (sysconf(_SC_PAGESIZE) / 1024))——因为 /proc/meminfo 的 MemFree: 也是 KB 单位,便于比对。
-
sysinfo()不区分MemFree和Available,它等价于内核的nr_free_pages,即真正未被使用的物理页,不含可回收的 page cache - 如果业务关心“用户态实际能用的内存”,应优先看
/proc/meminfo中的MemAvailable:,sysinfo()的结果会明显偏低(尤其在缓存较多时) - 调用前记得
#include <sys></sys>和<unistd.h></unistd.h>,结构体字段名是freeram,不是free_ram或freeMemory
Windows 上必须用 GlobalMemoryStatusEx()
Windows 没有类 Unix 的统一内存视图,GlobalMemoryStatusEx() 是唯一推荐方式。它返回的 ullAvailPhys 字段才是“当前可用物理内存字节数”,对应任务管理器里“可用”那一栏。
别用已废弃的 GlobalMemoryStatus():它只支持 32 位 dwAvailPhys,在 >4GB 内存机器上会溢出归零——这个 bug 在真实生产环境里踩过不止一次。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 必须初始化
MEMORYSTATUSEX结构体的dwLength = sizeof(MEMORYSTATUSEX),否则调用失败且GetLastError()可能返回ERROR_INVALID_PARAMETER -
ullAvailPhys包含可回收的 standby list(类似 Linux 的 page cache),所以数值通常显著高于 Linux 的MemFree:,但接近MemAvailable: - 头文件是
<windows.h></windows.h>,链接时不需要额外 lib,但需确保目标 Windows 版本 ≥ XP SP2(基本无兼容问题)
跨平台封装要注意 MemAvailable 和 ullAvailPhys 的语义差异
Linux 的 MemAvailable: 和 Windows 的 ullAvailPhys 虽然都叫“可用”,但算法逻辑不同:前者是内核估算的可立即分配页数(考虑 page cache、slab 等可回收项),后者是 Windows 内存管理器维护的 standby + free 页面总和。两者数值可能差 1–3 GB,不能简单等同。
- 若封装成统一接口,建议函数名明确带语义,比如
get_estimated_available_physical_memory_bytes(),避免误导调用方认为这是“绝对空闲” - Linux 下读
/proc/meminfo更准(尤其要匹配监控指标时),但需自行 parse;一行命令式读取:grep MemAvailable /proc/meminfo | awk '{print $2}',注意单位是 KB - macOS 不在此列——它没有直接对应概念,
host_statistics()返回的avail_target是压力阈值,不是实时值;真要获取得走vm_stat并算free + inactive,误差更大
sysinfo() 返回值为 0 不一定代表 OOM
sysinfo() 成功时返回 0,失败返回 -1;但它从不因内存不足而失败。如果你看到 freeram == 0,说明物理页完全被占用(不含可回收缓存),此时系统很可能已开始 swap 或 kill 进程,但 sysinfo() 本身不会报错。
- 检查失败必须用
if (sysinfo(&info) == -1),而不是if (!info.freeram) -
freeram == 0在容器环境里很常见(cgroup memory limit 限制了可用范围),不代表宿主机 OOM,需结合/sys/fs/cgroup/memory/memory.usage_in_bytes判断 - 高频轮询(如每秒多次)没必要——内核不保证实时更新,两次调用间隔太短可能拿到相同值;一般 1–5 秒粒度足够
实际写的时候,别为了“跨平台”硬套一层抽象。该 Linux 就用 sysinfo() 或 /proc/meminfo,该 Windows 就老老实实调 GlobalMemoryStatusEx()。语义差异藏不住,强行统一反而让使用者更难 debug。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










