win和linux c++统计并打印当前进程内存占用
·
VmSize 和 VmRSS 是 Linux 系统中用来描述进程内存使用情况的两个关键指标,它们来自 /proc/<pid>/status 文件。虽然 Windows 没有完全相同的术语,但可以通过等效方式获取类似信息。
下面详细解释这两个概念:
🔍 1. VmSize(Virtual Memory Size)
- 全称:Virtual Memory Size
- 单位:kB(千字节)
- 含义:进程当前使用的虚拟内存总量
- 包括:
- 可执行代码(text segment)
- 堆(heap,如
malloc、new分配) - 栈(stack)
- 共享库(如 libc.so、libopencv.so)
- 内存映射文件(mmap)
- GPU 显存映射(如 CUDA 分配)
- 不一定是物理内存占用
✅ 类比:你“申请”了多少地址空间
❌ 不代表实际消耗多少 RAM
📌 示例
VmSize: 15480 kB
表示该进程总共占用了约 15.5MB 的虚拟地址空间。
🔍 2. VmRSS(Resident Set Size)
- 全称:Resident Set Size
- 单位:kB(千字节)
- 含义:进程当前占用的物理内存(RAM)大小
- 说明:
- 这部分内存是“常驻”在物理内存中的,正在被使用
- 不包含已被换出到 swap 的页面
- 不包含未加载进内存的 mmap 文件页
- 最接近“真实内存消耗”的指标
✅ 类比:你真正“吃掉”了多少内存(RAM)
📌 示例
VmRSS: 8700 kB
表示该进程当前占用了约 8.7MB 的物理内存。
🆚 VmSize vs VmRSS 对比
| 项目 | VmSize |
VmRSS |
|---|---|---|
| 类型 | 虚拟内存 | 物理内存 |
| 是否反映真实 RAM 占用 | ❌ 否 | ✅ 是 |
| 包含 mmap 文件映射? | ✅ 是 | ⚠️ 只包含已加载进内存的部分 |
| 是否受 swap 影响? | ❌ 不影响 | ✅ 已 swap 出去的部分不计入 |
| 增长快意味着什么? | 地址空间扩张(可能泄漏) | 实际内存压力增大(可能导致 OOM) |
💡 举个例子
假设你用 mmap 映射了一个 1GB 的大文件:
void* ptr = mmap(NULL, 1UL << 30, PROT_READ, MAP_PRIVATE, fd, 0);
VmSize会增加 ~1GB(因为你申请了这么大地址空间)VmRSS只增加你实际访问过的页面(比如你只读了前 10MB,则 RSS 只增 ~10MB)
这就是为什么有些程序 VmSize 很大但系统并不卡顿的原因。
🖥️ Windows 上的等价概念
Windows 没有 VmSize / VmRSS,但有对应指标:
| Linux | Windows 等价 | API |
|---|---|---|
VmSize |
PagefileUsage | GetProcessMemoryInfo.PagefileUsage |
VmRSS |
WorkingSetSize | GetProcessMemoryInfo.WorkingSetSize |
Windows 示例对应关系:
PROCESS_MEMORY_COUNTERS pmc;
GetProcessMemoryInformation(hProcess, &pmc, sizeof(pmc));
std::cout << "VmSize (approx): " << pmc.PagefileUsage / 1024 << " KB\n";
std::cout << "VmRSS (approx): " << pmc.WorkingSetSize / 1024 << " KB\n";
🛠️ 如何监控这些值?
Linux 脚本方式
# 查看当前进程的内存
cat /proc/self/status | grep -E "VmSize|VmRSS"
# 或查看某个 PID
cat /proc/1234/status | grep -E "VmSize|VmRSS"
C++ 中打印(跨平台封装)
#ifdef _WIN32
#include <windows.h>
#include <psapi.h>
#pragma comment(lib, "psapi.lib")
#else
#include <fstream>
#include <cstdlib>
#endif
static void printMemoryInfo(const std::string& tag) {
std::cout << "=== Memory Info - " << tag << " ===" << std::endl;
#ifdef _WIN32
// Windows: 使用 GetProcessMemoryInfo
HANDLE hProcess = GetCurrentProcess();
PROCESS_MEMORY_COUNTERS pmc;
if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
SIZE_T vm_size = pmc.PagefileUsage; // 近似 Virtual Memory
SIZE_T rss = pmc.WorkingSetSize; // 物理内存使用 (RSS)
std::cout << "VmSize (Pagefile): " << vm_size / 1024 << " KB" << std::endl;
std::cout << "VmRSS (Working Set): " << rss / 1024 << " KB" << std::endl;
}
else {
std::cout << "Failed to get memory info on Windows." << std::endl;
}
#else
// Linux: 读取 /proc/self/status
std::ifstream file("/proc/self/status");
std::string line;
if (file.is_open()) {
while (std::getline(file, line)) {
if (line.find("VmRSS") != std::string::npos ||
line.find("VmSize") != std::string::npos) {
std::cout << line << std::endl;
}
}
file.close();
}
else {
std::cout << "Failed to open /proc/self/status" << std::endl;
}
#endif
std::cout << "===============================" << std::endl;
}
✅ 总结
| 名称 | 含义 | 关键理解 |
|---|---|---|
VmSize |
虚拟内存大小 | “我申请了多少地址空间” |
VmRSS |
常驻物理内存 | “我实际用了多少 RAM” |
🔔 重点关注
VmRSS:它是判断程序是否“吃内存”的核心指标。VmSize大不一定有问题,但VmRSS持续增长可能是内存泄漏。
如果你发现 VmRSS 随时间不断上升,而你应该释放的资源已经释放,那很可能存在 内存泄漏 或 缓存未清理 问题。可以用 Valgrind(Linux)或 Visual Studio 内存工具(Windows)进一步分析。
更多推荐




所有评论(0)