GlobalMemoryStatusEx获取总内存和使用率需初始化MEMORYSTATUSEX结构体并设dwLength为sizeof(MEMORYSTATUSEX),ullTotalPhys返回字节级总物理内存,dwMemoryLoad直接提供0–100整数百分比,无需自行计算。

Windows 下用 GlobalMemoryStatusEx 获取总内存和使用率
Windows 提供了最稳定、兼容性最好的方式:调用 GlobalMemoryStatusEx。它返回 MEMORYSTATUSEX 结构,其中 ullTotalPhys 是总物理内存字节数,dwMemoryLoad 是 0–100 的整数利用率(百分比),无需自己计算。
注意点:
-
GlobalMemoryStatusEx必须传入已初始化的MEMORYSTATUSEX,且dwLength字段必须设为sizeof(MEMORYSTATUSEX),否则返回失败 - 该函数在 Windows XP SP2+ 可用,旧系统需降级用
GlobalMemoryStatus(仅支持 4GB 以下内存) -
dwMemoryLoad是近似值,基于当前可用内存与总量的比例估算,不是实时采样,但足够用于监控告警
MEMORYSTATUSEX memInfo{};
memInfo.dwLength = sizeof(memInfo);
if (GlobalMemoryStatusEx(&memInfo)) {
uint64_t totalMB = memInfo.ullTotalPhys / (1024 * 1024);
int usagePercent = memInfo.dwMemoryLoad; // 直接就是 0~100
}Linux 下读取 /proc/meminfo 解析 MemTotal: 和 MemAvailable:
Linux 没有统一 API,标准做法是解析 /proc/meminfo。关键字段是 MemTotal:(总物理内存)和 MemAvailable:(内核估算的可立即分配内存)。利用率应按 (MemTotal - MemAvailable) / MemTotal 计算,而非用 MemUsed(该值不包含 page cache 等可回收项,会高估)。
常见错误:
立即学习“C++免费学习笔记(深入)”;
- 直接用
MemFree计算利用率 —— 它忽略 buffer/cache,结果偏低 - 没跳过空行或注释行,导致解析失败
- 未处理单位(
kB是默认单位,数值后带空格)
std::ifstream f("/proc/meminfo");
std::string line;
uint64_t totalKB = 0, availKB = 0;
while (std::getline(f, line)) {
if (line.rfind("MemTotal:", 0) == 0) totalKB = std::stoull(line.substr(9)) * 1024;
else if (line.rfind("MemAvailable:", 0) == 0) availKB = std::stoull(line.substr(13)) * 1024;
}
double usage = (totalKB > 0) ? (1.0 - static_cast<double>(availKB) / totalKB) * 100 : 0;跨平台封装时别硬写宏判断,优先用 ifdef _WIN32 分支
混合项目中,不要试图用第三方库(如 Boost.System)抽象内存查询 —— 它们往往只返回总内存,不提供利用率,或依赖 shell 命令(不可靠)。最简方案是手动分支:
- Windows 走
GlobalMemoryStatusEx - Linux 走
/proc/meminfo - macOS 需用
sysctlbyname("hw.memsize")获取总量,但无直接等价于MemAvailable的接口;可用vm.stats.vm.v_free_count * pagesize估算空闲页,再推导利用率(精度略低)
若只支持 Win/Linux,#ifdef _WIN32 / #else 就够用,避免引入构建复杂度。
获取到的数值单位和精度陷阱
所有平台返回的“总内存”都是字节级,但实际显示建议转成 MiB(1024×1024)而非 MB(1000×1000),否则和系统工具(如任务管理器、free -h)显示不一致。
利用率计算要防除零和浮点精度问题:
- 总内存为 0 时直接返回 0%,避免崩溃
- 用
double计算,避免整数除法截断(如(1024 / 2048) * 100得 0) - Linux 的
MemAvailable在低内存压力下可能略高于MemTotal(内核估算误差),需做std::min(availKB, totalKB)保护
真正难的不是读数据,而是理解每个字段背后的操作系统语义 —— 特别是“可用内存”在不同内核版本中定义略有变化,生产环境务必在目标发行版上实测验证。


















