vmrss是linux下最可靠的进程物理内存占用指标,单位kb,反映驻留集大小;需从/proc/self/status中提取,不包含swap和未映射内存,比vmsize更贴近真实ram使用。

Linux 下用 /proc/self/status 读取 VmRSS
Linux 系统中,当前进程的物理内存占用(即实际使用的堆+栈+数据段等)最可靠指标是 VmRSS,它反映驻留集大小(Resident Set Size),单位为 KB。注意这不是“纯堆”,但对绝大多数场景(如监控内存暴涨、判断是否泄漏)比 VmSize 更有意义。
实操建议:
- 打开
/proc/self/status文件,逐行扫描以VmRSS:开头的行,用sscanf提取数值 - 不要依赖
VmData或VmStk推算堆——内核不保证它们与malloc分配的堆严格对应,且线程栈、mmap 区域等会干扰 - 该方式无额外分配,开销极小,适合高频采样(如每秒一次)
- 需包含
<fstream></fstream>和<string></string>,权限无需 root(/proc/self/对本进程始终可读)
size_t get_rss_kb() {
std::ifstream f("/proc/self/status");
std::string line;
while (std::getline(f, line)) {
if (line.rfind("VmRSS:", 0) == 0) {
return std::stoul(line.substr(6));
}
}
return 0;
}
Windows 下调用 GetProcessMemoryInfo 获取 WorkingSetSize
Windows 没有直接等价于 VmRSS 的文件接口,必须用 PSAPI。核心是 GetProcessMemoryInfo 填充 PROCESS_MEMORY_COUNTERS 结构体,其中 WorkingSetSize 字段(单位字节)最接近 Linux 的 VmRSS 含义。
实操建议:
- 链接时需加
psapi.lib,头文件为<psapi.h></psapi.h> - 必须传入当前进程句柄:
GetCurrentProcess(),不能用NULL或硬编码 PID -
PagefileUsage是虚拟内存用量,容易误判为“堆占用”,实际含未提交的保留页,不推荐用于堆监控 - 首次调用可能略慢(内核收集数据),后续调用很快
#include <psapi.h>
size_t get_working_set_bytes() {
PROCESS_MEMORY_COUNTERS pmc;
if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
return pmc.WorkingSetSize;
}
return 0;
}</psapi.h>
为什么不用 mallinfo 或 malloc_stats
mallinfo 在 glibc 2.33+ 已被标记为废弃,返回值语义模糊:它只统计 malloc 管理器内部的块状态(如 uordblks 是已分配但未 free 的字节数),但不包括 mmap 分配的大块、C++ new 可能绕过 malloc、以及线程私有 arena 的延迟释放——导致结果常显著低于 VmRSS。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
实操建议:
- 避免在新项目中使用
mallinfo;若维护旧代码,至少要和VmRSS对比验证偏差 -
malloc_stats()只打印到 stderr,无法编程获取,且输出格式无保证,不适合自动化 - 即使你只用
malloc,也应优先信VmRSS/WorkingSetSize—— 它们反映 OS 真实回收压力
C++ 标准库没有跨平台堆内存查询接口
标准 C++ 不提供获取堆内存占用的函数,std::allocator 不跟踪总量,new_handler 也无法反查已用大小。所有可行方案都依赖操作系统原语。
这意味着:
- 写跨平台代码时,必须预处理器分支:
#ifdef _WIN32/#else(Linux/macOS) - macOS 需用
task_info+TASK_BASIC_INFO,字段是resident_size,不是VmRSS,但语义一致 - 容器自身
capacity()或size()仅反映逻辑用量,和物理内存占用可能差数倍(尤其涉及 small string optimization、预留空间、内存碎片)
真正棘手的点在于:你拿到的数字永远是快照,而堆内存波动剧烈。如果要做泄漏检测,别只看单次值,得结合多次采样趋势、分配点堆栈(如用 libbacktrace 或 AddressSanitizer)来定位。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










