windows下用globalmemorystatusex获取实时物理内存使用率最可靠,需初始化dwlength字段,通过ullavailphys与ulltotalphys计算百分比;linux应读取/proc/meminfo中的memavailable与memtotal计算,避免使用已废弃的globalmemorystatus或memfree。

Windows 下用 GlobalMemoryStatusEx 获取实时物理内存使用率
Windows 没有直接返回“可用内存百分比”的单一 API,GlobalMemoryStatusEx 是唯一稳定、无需管理员权限、能获取准确物理内存状态的系统调用。它返回的是 MEMORYSTATUSEX 结构,关键字段是 ullAvailPhys(当前可用字节数)和 ullTotalPhys(总物理字节数),二者相除即得可用率。
常见错误是误用已废弃的 GlobalMemoryStatus(精度低、不支持 >4GB 内存),或把 ullAvailPageFile 当作物理内存指标——那是页面文件容量,和物理内存无关。
- 必须初始化
dwLength字段为sizeof(MEMORYSTATUSEX),否则调用失败且不报错 - 返回值为
FALSE时需检查GetLastError(),但多数情况是结构体未初始化导致 - 计算百分比建议用
(double)mem.ullAvailPhys / mem.ullTotalPhys * 100.0,避免整数截断
Linux 下读取 /proc/meminfo 并解析 MemAvailable
Linux 不推荐用 free 命令输出做解析(格式易变、依赖 locale),应直接读取 /proc/meminfo 文件。核心指标是 MemAvailable(内核 3.14+ 提供),它比 MemFree 更真实反映可立即分配的内存,已扣除不可回收缓存等干扰项。
容易踩的坑是:老内核(MemAvailable,只能退回到 MemFree + Buffers + Cached - Shmem 近似估算,但误差可能达 10% 以上;另一常见错误是忽略单位(所有字段单位都是 kB,不是字节)。
- 逐行读取文件,匹配以
MemAvailable:开头的行,用sscanf(line, "MemAvailable: %lld kB", &avail_kb) -
MemTotal:行同理获取总量,再算百分比:(double)avail_kb / total_kb * 100.0 - 注意
/proc/meminfo是实时虚拟文件,无需缓存,每次读取即最新状态
跨平台绘图:用 gnuplot 实时生成内存百分比走势图
自己写 GUI 绘图太重,轻量级方案是把采集数据写入 CSV,用 gnuplot 启动管道实时刷新图表。关键是控制采样频率与绘图窗口更新节奏,避免 CPU 占用飙升。
不要用 system("gnuplot ...") 每次启动新进程——开销大且难同步;正确做法是保持一个长生命周期的 gnuplot 进程,通过 stdin 输入命令和数据。
- C++ 中用
popen("gnuplot -persistent", "w")打开写入管道 - 每轮采集后写入:
"replot '<data.csv>' using 1:2 with lines title 'Available %'"</data.csv> - CSV 每行格式:
timestamp,percent,时间戳用std::chrono::steady_clock::now().time_since_epoch().count() - gnuplot 脚本里加
set yrange [0:100]和set ylabel "Available (%)"避免纵轴飘移
负载统计不能只看内存:补充 GetSystemTimes(Windows)和 /proc/stat(Linux)
内存百分比只是负载的一部分。CPU 负载需单独采集:Windows 下 GetSystemTimes 返回空闲/内核/用户时间,差值比得出整体占用率;Linux 则解析 /proc/stat 的第一行(cpu 开头),取前四个字段(user, nice, system, idle)累加后算 idle 占比。
注意:两次采样必须间隔至少 100ms,否则 idle 时间差可能为 0,导致 CPU 使用率算成 100%;另外 /proc/stat 的 idle 包含 iowait,若要排除 I/O 等待,得用 user + nice + system 占总时间的比例。
- Windows 中
GetSystemTimes返回的 FILETIME 是 100ns 单位,需转为毫秒再做减法 - Linux 解析
/proc/stat时跳过首行空格,用sscanf(buf, "cpu %lld %lld %lld %lld", &u, &n, &s, &i)安全读取 - 内存 + CPU 两个指标应统一采样时间戳,避免走势图出现错位抖动
实际部署时,内存可用率的“动态”体现在采样频率(建议 1–2 秒),而“走势图表”的稳定性取决于 gnuplot 缓存机制和 CSV 文件滚动策略——别让日志文件无限增长,到一定大小就截断或轮转。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











