linux下读取/proc/self/status中的vmrss字段(单位kb)是最直接获取进程驻留物理内存的方式,需按关键字匹配而非固定行号,结合/proc/meminfo或sysconf动态获取总内存以计算百分比,windows则用getprocessmemoryinfo的workingsetsize配合globalmemorystatusex。

Linux 下用 /proc/self/status 读取 VmRSS 是最直接方式
Linux 系统中,每个进程的内存使用信息都实时暴露在 /proc/[pid]/status 里,VmRSS 字段(单位 KB)代表当前驻留物理内存大小。它不包含 swap,也不含 page cache,是真正“占着物理内存”的那部分,和任务管理器里看到的“物理内存占用”语义最接近。
实操建议:
- 打开
/proc/self/status,逐行扫描以VmRSS:开头的行,用sscanf提取数值 - 不要依赖固定行号——字段顺序可能随内核版本微调,必须按关键字匹配
- 读取是轻量级系统调用(
open + read + close),每秒几十次完全无压力 - 注意:该值是瞬时快照,需自行做差分或滑动窗口计算变动率,系统不提供“百分比变动”原生指标
计算百分比要先知道总物理内存,别硬编码 1024*1024*8
拿 VmRSS 除以总内存才能得到百分比。但总内存不能写死——不同机器差异极大,且运行时可能被 cgroup 限制。正确做法是读 /proc/meminfo 的 MemTotal:,或更稳妥地调用 sysconf(_SC_PHYS_PAGES) × sysconf(_SC_PAGESIZE)。
常见错误现象:
- 用
get_total_memory()返回 8GB 固定值 → 在 32GB 服务器上显示永远只有 25%,误导性极强 - 只读
/proc/meminfo一次然后缓存 → 忽略了热插拔内存或容器内存配额(cgroup v1 的memory.limit_in_bytes) - 没处理 cgroup 场景 → Docker/K8s 中进程看到的
MemTotal仍是宿主机总量,但实际可用受限,此时应优先查/sys/fs/cgroup/memory/memory.limit_in_bytes
Windows 上得用 GetProcessMemoryInfo 配合 GlobalMemoryStatusEx
Windows 没有统一的 procfs,得走 Win32 API:GetProcessMemoryInfo 填充 PROCESS_MEMORY_COUNTERS 结构体,其中 WorkingSetSize 字段(字节)近似于 Linux 的 VmRSS;总内存则靠 GlobalMemoryStatusEx 返回的 ullTotalPhys。
关键细节:
-
WorkingSetSize包含共享页(如 DLL 代码段),但不含已换出页,和用户感知基本一致 - 必须链接
psapi.lib,且在 Windows 7+ 才保证WorkingSetSize稳定可靠(旧版可能返回 0) - 调用前需用
OpenProcess获取自身句柄,权限要求低(PROCESS_QUERY_INFORMATION即可) - 别用
GetPerformanceInfo—— 它返回的是整个系统的全局统计,不是当前进程的
跨平台封装时,变动指标得自己算,系统不提供 delta
所有平台都只提供瞬时绝对值(KB 或字节),没有“过去 1 秒涨了 2%”这种现成接口。要做变动指标,至少得维护两个时间点的样本:
- 建议采样间隔 ≥ 100ms:太短会导致噪声大(尤其 Linux 下
/proc文件读取有微小抖动);太长则丢失快速波动 - 百分比变动 =
(current_rss - last_rss) * 100.0 / total_mem,不是(current_pct - last_pct)—— 后者会放大浮点误差 - 注意整数溢出:
VmRSS在大内存机器上可达数十 GB,用long long存储,别用int - 如果目标是监控告警,建议加简单滤波(比如三帧中位数)再送入判断逻辑,避免毛刺触发误报
真正的难点不在读内存,而在定义“变动”本身——是看 1 秒增幅?还是 5 秒均值斜率?还是 RSS 连续 3 次超过阈值?这些业务逻辑必须由你决定,系统 API 只负责把数字给你。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











