linux下用sysinfo获取可用物理内存最直接:调用sysinfo()填充struct sysinfo,取freeram字段乘以getpagesize()得字节数,该值已包含可立即回收的pagecache和slab,语义准确且轻量可靠。

Linux 下用 sysinfo 获取可用物理内存最直接
Linux 系统里,sysinfo 是最轻量、最可靠的获取方式,它返回的 freeram 字段就是当前可用物理内存页数,乘以 getpagesize() 就是字节数。注意不是 totalram - usedram,因为内核会缓存、回收,freeram 已包含可立即回收的 pagecache 和 slab 可回收部分。
实操建议:
-
sysinfo需要#include <sys></sys>,返回值为 0 表示成功 - 别直接用
mem_unit字段——它在旧内核可能为 0,应统一用getpagesize() - 结果单位是字节,建议转成 MiB 显示:
freeram * getpagesize() / 1024 / 1024 - 避免高频调用(如每毫秒),
sysinfo虽快但仍有锁开销;监控场景建议 1–5 秒间隔
Windows 上必须用 GlobalMemoryStatusEx,GlobalMemoryStatus 已废弃
GlobalMemoryStatus 在 Windows 8+ 上无法正确报告大于 4GB 的内存,必须用支持 ULARGE_INTEGER 的 GlobalMemoryStatusEx。关键字段是 ullAvailPhys,它对应“当前未分配且未被缓存占用的物理内存”,和 Linux 的 freeram 语义最接近。
实操建议:
- 需定义
MEMORYSTATUSEX mem; mem.dwLength = sizeof(mem);,否则调用失败返回 false - 不要读
ullTotalPhys减ullTotalPhys - ullAvailPhys来算“已用”,这会漏掉 standby/modified list 内存,和实际压力不匹配 - 链接时加
-lpsapi(MinGW)或确保Psapi.lib在链接器输入中(MSVC) - 该函数线程安全,但频繁调用仍建议缓存结果(尤其在服务进程中)
macOS 用 host_statistics64 + HOST_VM_INFO64 才准确
macOS 没有类似 sysinfo 的简单接口。sysctl 的 vm.pages_free 等参数只反映部分状态,且 macOS 12+ 后已被标记为 deprecated。真正可靠的是 Mach API:host_statistics64 查询 HOST_VM_INFO64,其中 free_count 字段才是当前完全空闲页数(不含压缩、inactive、speculative 页)。
实操建议:
- 需
#include <mach></mach>和<mach></mach>,链接-framework CoreServices - 必须用
host_statistics64(不是host_statistics),否则 64 位计数会截断 -
free_count单位是页,需乘host_page_size(不能硬写 4096,ARM64 可能是 16KB) - 首次调用可能失败(权限或 host port 无效),建议 fallback 到
sysctl("hw.memsize")仅作总量参考,不用于可用值
跨平台封装时,std::optional<size_t></size_t> 比返回 -1 更安全
各平台获取逻辑失败原因不同:Linux sysinfo 可能因权限失败(极少见),Windows GlobalMemoryStatusEx 可能因结构体长度不对失败,macOS Mach 调用可能因 host port 失效失败。用 -1 表示错误容易和真实值(如 0 字节可用)混淆。
实操建议:
- 返回类型统一用
std::optional<size_t></size_t>(C++17),调用方显式检查has_value() - 不要在失败时抛异常——内存监控本身是诊断辅助,不应中断主流程
- 日志中记录失败原因(如 “GlobalMemoryStatusEx failed with GetLastError()=122”),便于定位环境问题
- 若需 C 接口兼容,可提供
bool get_available_physical_memory(size_t* out),靠返回值判错
真正难的不是取值,而是理解“可用”的定义在各系统间并不等价:Linux 的 freeram 包含可回收 cache,Windows 的 ullAvailPhys 不含 standby list,macOS 的 free_count 完全不计压缩内存。做趋势对比可以,但跨平台绝对数值对齐没有意义。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











