Windows需用GlobalMemoryStatusEx计算可用内存百分比,设dwLength后以ullAvailPhys/ullTotalPhys×100;Linux应优先读/proc/meminfo中MemAvailable,缺失时退化为MemFree+Buffers+Cached−Shmem;跨平台采样须用steady_clock动态休眠并避免浮点误差。

Windows下用GlobalMemoryStatusEx获取真实可用物理内存百分比
Windows不直接暴露“当前可用内存百分比”这个计算值,必须自己算——而且得用GlobalMemoryStatusEx,GlobalMemoryStatus已废弃且精度不足。关键不是读ullAvailPhys,而是拿它除以ullTotalPhys,再乘100。注意:返回值是MEMORYSTATUSEX结构体,dwLength字段必须手动设为sizeof(MEMORYSTATUSEX),否则调用失败返回false,很多代码漏这步。
-
ullAvailPhys是当前可立即分配的物理内存字节数(含备用页、修改页等可回收部分) -
ullTotalPhys是总安装物理内存,不是“可用上限”,所以百分比可能短暂超过100%(比如系统压缩内存或启用Pagefile时的统计口径差异) - 每秒采样一次足够,高频调用无意义,该API本身不耗资源但频繁计算浮点除法没必要
Linux下读/proc/meminfo并避开MemAvailable的兼容性陷阱
Linux没统一API,最稳方式是解析/proc/meminfo。别只看MemFree——它忽略page cache、slab等可回收内存,结果严重偏低。优先用MemAvailable(内核3.14+才有),但得先检查该字段是否存在;若不存在(如CentOS 6/7旧内核),退回到MemFree + Buffers + Cached - Shmem近似估算。
-
MemAvailable字段缺失时,grep MemAvailable /proc/meminfo会空输出,需用grep -q判断后分支处理 - 所有数值单位是kB,别忘了除1024转MB、再除总内存算百分比
-
MemTotal是实际可用物理内存上限,不含swap,别误用TotalMemory(那是/proc/meminfo里没有的伪字段)
C++跨平台采集循环中避免阻塞与精度漂移
做动态走势图表,核心是稳定时间间隔+无锁数据推送。别用std::this_thread::sleep_for硬等——系统调度延迟会导致采样间隔抖动,累积几小时后图表时间轴歪斜。正确做法:记录上一次采集的std::chrono::steady_clock::now(),每次循环计算差值,只sleep剩余毫秒数。
- 用
std::vector<:pair double>></:pair>存(时间戳, 内存使用率),时间戳用steady_clock::to_time_t或直接存毫秒整数,别用system_clock(可能因NTP校时跳变) - 内存百分比建议保留一位小数,
std::round(usage * 10.0) / 10.0,避免浮点误差导致图表锯齿 - Linux下
fopen("/proc/meminfo", "r")比std::ifstream快且稳定,后者在高IO负载时偶发卡顿
生成简易动态图表前先确认终端是否支持ANSI颜色与重绘
命令行实时走势图表本质是覆盖式打印,依赖终端支持\r回车和ANSI控制序列。先检测isatty(STDOUT_FILENO),再检查环境变量TERM是否含xterm、screen或linux——Windows CMD默认不支持ANSI,得调用SetConsoleMode开启ENABLE_VIRTUAL_TERMINAL_PROCESSING标志。
立即学习“C++免费学习笔记(深入)”;
- 每行末尾必须用
\r而非\n,否则滚动而非覆盖 - 用
\033[2K清空整行再打印新数据,避免残留字符干扰 - 负载报告里
load average要读/proc/loadavg前三列(1/5/15分钟),别只取第一个——用户真正关心的是趋势,不是瞬时峰值
实际最难的不是读内存,是让不同内核版本、不同终端环境下输出始终对齐且不乱码。跑之前先在目标机器上echo -e "\033[2K\033[0mTest"验证ANSI支持,比写完发现图表全糊成一行强得多。


















