vmrss字段表示进程实际使用的物理内存页,单位kb,是/proc/self/status中最可靠的方式获取当前进程物理内存占用;需逐行读取匹配“vmrss:”并用std::stoi解析,避免scanf格式化读取失败。

Linux 下用 /proc/self/status 读取物理内存使用量
Linux 系统中,/proc/self/status 是最轻量、最可靠的方式获取当前进程的物理内存占用。它不依赖外部库或特权,且字段稳定(内核 2.6+ 均支持)。关键字段是 VmRSS,单位为 KB,代表进程实际使用的物理内存页(Resident Set Size),不是虚拟内存或共享内存估算值。
实操建议:
- 每次读取需重新打开并解析文件,避免缓存
VmRSS行位置——内核可能动态增减字段顺序 - 用
std::string逐行读,匹配以"VmRSS:"开头的行,再用std::stoi提取数值;别用scanf直接格式化读,易因空格/制表符错位失败 - 注意
VmRSS是近似值:内核统计有延迟(通常
计算百分比需先获取系统总物理内存
仅靠 VmRSS 无法得出百分比,必须知道系统总物理内存(MemTotal)。它在 /proc/meminfo 中,单位也是 KB。不能硬编码或查 sysconf(_SC_PHYS_PAGES),因为后者返回的是页数,未扣除内核保留内存,会导致百分比偏高(常高估 2%–5%)。
实操建议:
- 同样逐行读
/proc/meminfo,匹配"MemTotal:"行,提取数值后与VmRSS相除即可得百分比 - 不要复用同一个
std::ifstream对象去读两个文件——Linux 下/proc文件是动态生成的,多次读可能触发重置逻辑,导致读到旧数据 - 若需高频采样(如每 100ms 一次),可把
MemTotal缓存 1–2 秒,它极少变动;但VmRSS必须每次都读新值
Windows 下必须用 GetProcessMemoryInfo + GlobalMemoryStatusEx
Windows 没有等价于 /proc 的伪文件系统,必须调用 Win32 API。GetProcessMemoryInfo 返回 PROCESS_MEMORY_COUNTERS_EX 结构体,其中 WorkingSetSize 字段最接近 Linux 的 VmRSS(即当前驻留物理内存字节数);GlobalMemoryStatusEx 获取系统总物理内存(ullTotalPhys)。
实操建议:
- 链接时加
-lpsapi(MinGW)或确保Psapi.lib在链接路径中;MSVC 默认不自动链接 Psapi,会报LNK2019: unresolved external symbol -
WorkingSetSize包含共享页(如 DLL 代码段),但 Windows 不提供干净剥离版;若程序大量使用共享 DLL,该值会略高于实际独占内存,趋势仍可用 - 调用前检查
PROCESS_MEMORY_COUNTERS_EX::cb是否设为sizeof(PROCESS_MEMORY_COUNTERS_EX),否则 API 可能静默失败并返回 0
高频采样时的精度与开销平衡
每秒采样超 10 次时,I/O 和解析开销会明显影响目标进程自身性能,尤其在低配机器上。Linux 下单次 /proc/self/status 读取约 0.1–0.3ms(SSD),Windows API 调用约 0.05ms,但频繁调用仍可能干扰调度。
实操建议:
- 用
std::chrono::steady_clock控制间隔,别依赖sleep_for——它不保证唤醒精度,可能导致采样堆积 - 若只关心趋势而非绝对值,可改用
/proc/self/statm:它更小(单行,空格分隔),第 2 列是 RSS 页数,只需read(2)+ 手动 parse,快 30%–50% - 真正要长期监控时,别自己轮询;改用
perf(Linux)或 ETW(Windows)采集,它们由内核直接推送事件,无用户态开销
跨平台封装时,最容易被忽略的是 VmRSS 和 WorkingSetSize 的语义差异:前者不含 swap-in 过程中的页,后者可能含瞬时 page fault 引入的页。趋势对比没问题,但做精确内存泄漏判定时,得配合 mmap/VirtualAlloc 跟踪才可靠。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











