globalmemorystatusex 的 dwmemoryload 字段直接提供 0–100 整数内存使用率,计算公式为 (ulltotalphys - ullavailphys) / ulltotalphys × 100,其中 ullavailphys 已包含 standby 内存;调用前须初始化 dwlength 成员。

Windows下用 GlobalMemoryStatusEx 获取实时物理内存使用率
Windows没有直接暴露“当前可用物理内存百分比”的系统级指标,但 GlobalMemoryStatusEx 是唯一稳定、无需管理员权限、且能反映真实可用内存(含 standby + free)的API。它返回的 MEMORYSTATUSEX.dwMemoryLoad 就是系统定义的“内存使用率”,范围 0–100,计算逻辑为:(ullTotalPhys - ullAvailPhys) / ullTotalPhys * 100,注意这不是简单看 ullAvailPhys 占比——因为 Windows 把 standby 内存视作“可用但可回收”,而 ullAvailPhys 已包含这部分。
实操要点:
- 必须调用前初始化
MEMORYSTATUSEX.dwLength = sizeof(MEMORYSTATUSEX),否则返回 false -
dwMemoryLoad是整数百分比,不是浮点;若需更细粒度,自行用ullAvailPhys和ullTotalPhys计算浮点值 - 该值每秒变化可能不大,高频轮询(如
- 不支持 Windows XP 及更早系统,
GlobalMemoryStatus已废弃,不要用
Linux下读取 /proc/meminfo 中的 MemAvailable
Linux 从 3.14+ 内核开始在 /proc/meminfo 暴露 MemAvailable: 行,这是内核估算的真正可立即分配的内存(已剔除不可回收的 slab、page cache dirty 等),比单纯用 MemFree 或 Available(旧字段)靠谱得多。实际百分比就是 MemAvailable / MemTotal * 100。
常见误区和操作建议:
- 别解析
MemFree—— 它忽略大量可回收内存,结果严重偏低(尤其在缓存密集型场景) - 确保内核版本 ≥ 3.14;低于此版本
MemAvailable字段不存在, fallback 方案只能粗略用MemFree + Buffers + Cached - Shmem,但误差大 - 读取
/proc/meminfo是轻量系统调用,无需 root 权限,但要注意文件行顺序不固定,必须按字段名匹配,不能靠行号 - 示例提取逻辑:逐行读,找以
"MemAvailable:"开头的行,跳过空格后 parse 第一个数字(单位 KB)
C++跨平台封装时为什么不能只依赖 sysconf(_SC_PHYS_PAGES)
sysconf(_SC_PHYS_PAGES) 只返回总物理页数,没提供当前可用值,它甚至不涉及内存状态——只是个静态常量。想靠它算百分比?必须配合其他接口,比如 Linux 下仍得读 /proc/meminfo,macOS 下要用 host_statistics + HOST_VM_INFO64,Windows 下则完全无关。
跨平台陷阱:
- macOS 的
vm_statistics64返回的是 active/inactive/wire/pagedout 页面数,但“可用”需手动估算:free_count + inactive_count(近似),且受purgeable内存影响,无标准公式 - POSIX 标准里根本没有“可用内存”定义,所有
sysconf相关常量都不解决这个问题 - 试图用
mallinfo或malloc_stats?那是堆内存,和物理内存完全无关,数据不可比 - 结论:跨平台内存百分比必须分 OS 实现,没有统一 syscall 或 C++ 标准库函数
走势采集时容易被忽略的采样节奏与数值抖动问题
内存值本身波动剧烈——浏览器开个标签页、后台服务触发一次 GC 都可能让 MemAvailable 瞬间掉几百 MB。直接画原始点会满屏毛刺,看不出趋势。
实操建议:
- 基础采样间隔设为 2–5 秒;短于 1 秒不仅无效,还会因频繁读
/proc/meminfo或调用 API 增加内核负载 - 对原始值做滑动窗口平均(如 5 个点均值),或更稳妥地用指数加权移动平均(EWMA),α 取 0.2–0.3 效果通常比简单均值好
- 警惕
dwMemoryLoad在 Windows 上偶发跳变到 99/100(尤其低内存警告触发时),这不是 bug,是系统主动压测反馈,应视为有效信号而非噪声 - 记录时间戳务必用单调时钟(
std::chrono::steady_clock),避免 NTP 调整导致走势图时间轴错乱
真正的难点不在获取单点值,而在理解各平台“可用内存”的定义差异——Windows 的 standby、Linux 的 MemAvailable、macOS 的 purgeable,本质是不同内核的设计哲学,强行统一口径只会引入更大误差。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











