Linux系统不提供全局物理内存占用峰值,需自行周期采样/proc/meminfo中MemTotal与MemAvailable差值并记录最大值;进程级峰值可用/proc/[pid]/status的VmHWM字段。

Linux 下用 /proc/meminfo 无法直接拿到物理内存占用峰值
很多人一上来就查 /proc/meminfo,发现里面只有 MemTotal、MemAvailable、MemFree 这类瞬时值,但没有类似 “peak RSS” 的历史最大值字段——这是对的,/proc/meminfo 本身不记录峰值。系统内核确实不维护全局物理内存占用的历史峰值,它只暴露当前快照。
真正能拿到“进程级”内存峰值的是 /proc/[pid]/status 中的 VmHWM 字段(单位 KB),代表该进程自启动以来的最高驻留集大小(High Water Mark)。如果你要监控整个系统的物理内存使用峰值,必须自己做周期采样 + 记录最大值。
- 采样频率建议设为 1–5 秒,太密会增加 I/O 和解析开销,太疏可能错过短时尖峰
- 读取
/proc/meminfo中的MemTotal减去MemAvailable得到当前已用物理内存(近似值,不含 page cache 回收部分) - 用
std::max持续更新本地变量即可,不需要写文件或连数据库——除非你要跨重启持久化
C++ 读取 /proc/meminfo 的安全解析方式
直接用 std::ifstream 逐行读、用 std::string::find 找 ": " 然后 std::stoll 转数字是最常见也最易出错的做法。典型坑是:某行末尾有空格、字段名大小写混用(其实全小写)、某些发行版内核补丁导致字段顺序变动(比如 MemAvailable 在旧内核不存在)。
更稳妥的做法是:
立即学习“C++免费学习笔记(深入)”;
- 只依赖
MemTotal和MemFree(所有 Linux 内核都保证存在),用MemTotal - MemFree作为保守下界估算已用内存 - 若需更准,先检查
MemAvailable是否存在,再 fallback 到MemFree + Buffers + Cached组合计算(注意Cached在/proc/meminfo中实际叫Cached:,冒号后有空格) - 每一行用
sscanf(line.c_str(), "MemTotal: %lld kB", &val)更鲁棒,比字符串切分容错性强
Windows 上用 GetPerformanceInfo 获取内存峰值不现实
GetPerformanceInfo 返回的是当前内存使用快照(CommitTotal、PhysicalTotal),和 Linux 的 /proc/meminfo 类似,没有历史峰值字段。Windows 系统本身也不提供 API 直接返回“自开机以来物理内存使用的最高百分比”。你看到的资源监视器里那个“峰值”曲线,是它自己在后台持续采样并维护的本地状态。
所以 C++ 实现跨平台内存峰值监控时:
- Windows 必须自己调
GetPerformanceInfo或GlobalMemoryStatusEx做定时轮询,并用std::atomic_uint64_t更新峰值 - 不要尝试从 WMI 查询
Win32_OperatingSystem的MaxProcessMemorySize——那是单个进程限制,不是系统物理内存峰值 - 注意
GetPerformanceInfo需要链接psapi.lib,且返回结构体中内存单位是页面(dwPageSize),别忘了换算
避免把 VmHWM 当成系统峰值的常见误解
很多同学看到 /proc/self/status 里的 VmHWM 就以为这是“本机内存峰值”,其实它只是当前进程自己的峰值。即使你用 root 权限跑,它也不会累加所有进程的 VmHWM——因为多个进程共享 page cache、shared memory、buffers 等,简单相加会导致严重高估。
真正的系统级物理内存峰值,只能通过周期性读 /proc/meminfo 并记录 MemTotal - MemAvailable 的最大值得到。如果需要更高精度(比如排除 page cache 可回收部分),得结合 /proc/meminfo 中 Active(file)、Inactive(file) 等字段做加权估算,但这已经超出大多数监控场景的需求。
最常被忽略的一点是:容器环境(如 Docker)中,/proc/meminfo 默认显示宿主机视图,除非挂载了 cgroup v1 的 /sys/fs/cgroup/memory/ 下对应 memory.stat ——这时候就得切路径、换逻辑,不能无脑读 /proc/meminfo。


















