/proc/meminfo 不提供物理内存历史峰值,因其仅含瞬时快照;系统级峰值需程序持续采样MemTotal与MemAvailable差值并维护最大值。

Linux 下用 /proc/meminfo 读取物理内存峰值不准确,为什么?
因为 /proc/meminfo 中的 MemTotal、MemFree 等是瞬时快照,**没有“历史峰值”字段**。它不记录系统自启动以来的最高内存使用量——这是常见误解。真正能反映“物理内存占用峰值”的指标,在 Linux 上其实是 HighWaterMark 类信息,但仅对单个进程有效(如 /proc/[pid]/status 中的 VmHWM),系统级全局峰值需靠外部持续采样+维护最大值。
如何用 C++ 持续监控系统物理内存使用并记录峰值?
核心思路:定时读取 /proc/meminfo,自己计算并维护峰值。关键不是“一次读”,而是“多次读+比较”。示例逻辑:
// 伪代码示意,实际需加错误处理和 sleep 控制
long long peak_kb = 0;
while (running) {
auto used = get_mem_used_kb(); // 从 MemTotal - MemFree - Buffers - Cached 计算
if (used > peak_kb) peak_kb = used;
std::this_thread::sleep_for(1s);
}
-
MemAvailable比MemFree更合理,应优先用它估算“当前可用内存”,但峰值仍需基于MemTotal - MemAvailable的差值趋势推算 - 注意:Linux 内核 4.19+ 的
MemAvailable已包含 page cache 可回收部分,直接用MemTotal - MemAvailable得到的“已用”更贴近用户感知 - 采样间隔不宜过短(5s),可能错过短时峰值
Windows 上获取物理内存峰值只能靠 GetPerformanceInfo?
是的,Windows 没有类似 /proc 的文本接口,必须调用 Windows API。但要注意:GetPerformanceInfo 返回的 CommitTotal 和 CommitLimit 是页面文件相关,**不是物理内存峰值**;真正对应物理内存使用峰值的是 PERFORMACE_INFORMATION.PhysicalTotal 和 PhysicalUsed 的历史最大值——而该结构体本身不存历史,你仍需自己维护。
- 调用前需链接
psapi.lib,头文件为 -
GetPerformanceInfo返回的PhysicalUsed单位是页(通常 4KB),需乘以dwPageSize转为字节 - 该函数在低权限进程下可调用,但若被组策略禁用性能计数器,可能返回 0 或失败(错误码
ERROR_ACCESS_DENIED)
跨平台封装时,std::chrono 和文件 I/O 的陷阱
用 C++ 写跨平台内存监控工具时,最易出问题的不是算法,而是时间精度和路径处理:
- Linux 下读
/proc/meminfo是轻量系统调用,但频繁 open/read/close 仍可能触发内核锁争用;建议用std::ifstream并复用流对象,而非每次 new - Windows 下不要硬编码
C:\Windows\System32\,应通过GetSystemDirectory获取路径;且GetPerformanceInfo需要先调用一次获取缓冲区大小,再分配内存重试——漏掉这步会返回ERROR_INSUFFICIENT_BUFFER -
std::chrono::steady_clock是唯一可靠选择;用system_clock在 NTP 校时后可能导致采样间隔错乱
物理内存峰值不是内核自动保存的“仪表盘读数”,它是你程序主动观测、计算、比对出来的结果。最容易被忽略的,是把“瞬时使用量”误当作“峰值”,以及在多线程环境下未对峰值变量做原子更新或加锁。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











