c++如何获取系统的当前物理内存占用峰值监控实战分析 _ 监控接口【实战】

Linux 下用 /proc/meminfo 无法直接拿到物理内存占用峰值

很多人一上来就查 /proc/meminfo,发现里面只有 MemTotal、MemFree、MemAvailable 这类瞬时值,但没有 PeakRss 或类似字段——没错,Linux 内核**不维护全局物理内存占用历史峰值**。这个值根本不存在于系统接口里,硬查只会白忙。

真正能拿到的“峰值”,只存在于两个上下文里:

单个进程的 getrusage(RUSAGE_SELF, &ru) 返回的 ru.ru_maxrss(单位是 KB),这是该进程生命周期内驻留集(RSS)的最大值;系统级近似峰值只能靠周期采样 + 外部记录,例如每秒读一次 /proc/meminfo 中的 MemTotal – MemFree – Buffers – Cached – SReclaimable 算出近似已用内存,再自己比大小。

C++ 调用 getrusage 获取当前进程 RSS 峰值

getrusage 是 POSIX 标准接口,在 Linux/macOS/WSL 上都可用,Windows 需用 GetProcessMemoryInfo 替代(下节讲)。它返回的是进程自启动以来的**最大常驻内存(RSS)**,不是系统总内存峰值,但对监控自身服务是否内存泄漏极其关键。

示例代码片段:

立即学习“C++免费学习笔记(深入)”;

#include <sys/resource.h>#include <iostream><p>long get_peak_rss_kb() {struct rusage ru;if (getrusage(RUSAGE_SELF, &ru) == 0) {return ru.ru_maxrss; // Linux 返回 KB,macOS 返回 bytes(需判断 _SC_PAGESIZE)}return -1;}

注意点:

ru_maxrss 在 Linux 上单位是 KB,在 macOS 上是字节,可通过 sysconf(_SC_PAGESIZE) 和 getpagesize() 辅助判断平台;该值只增不减,且仅反映用户态分配+内核为该进程分配的页框,不含共享库重复计数;调用开销极小,可放心在性能敏感服务中每几秒采集一次。

Windows 上用 GetProcessMemoryInfo 替代 getrusage

Windows 没有 getrusage,但 psapi.h 提供的 GetProcessMemoryInfo 可以拿到 PROCESS_MEMORY_COUNTERS_EX::PeakWorkingSetSize,单位字节,含义最接近 Linux 的 ru_maxrss。

关键步骤:

链接 Psapi.lib(MSVC)或加 -lpsapi(MinGW);必须用 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ 权限打开当前进程句柄;结构体要用 PROCESS_MEMORY_COUNTERS_EX(不是旧版 PROCESS_MEMORY_COUNTERS),否则 PeakWorkingSetSize 字段不存在;该值受 Windows 工作集策略影响,可能比实际物理页分配略宽松,但仍是生产环境唯一可用的进程级峰值指标。

系统级“物理内存占用峰值”只能靠采样 + 自维护

如果你真需要整个系统的物理内存使用历史最高点(比如做告警阈值基线),别指望内核提供现成字段。可行做法是:

定时(如 1s 间隔)读取 /proc/meminfo,提取 MemTotal:、MemFree:、Buffers:、Cached:、SReclaimable: 四行;按公式计算近似已用内存:MemTotal – MemFree – Buffers – Cached – SReclaimable(单位 kB);自己维护一个 static long long system_peak_kb = 0,每次更新时比较取大;注意:该值会受 page cache 回收、cgroup 限制、zram 压缩等干扰,不能用于精确审计,只适合趋势监控。

真正棘手的不是怎么算,而是采样频率和精度的权衡——太密增加 I/O 和锁争用(/proc/meminfo 读取会触发内核统计),太疏又可能错过尖峰。线上建议起始设为 3~5 秒,再根据 top -b -n1 | head -20 观察 Mem: 行波动幅度动态调整。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。