VmSizeVmRSS 是 Linux 系统中用来描述进程内存使用情况的两个关键指标,它们来自 /proc/<pid>/status 文件。虽然 Windows 没有完全相同的术语,但可以通过等效方式获取类似信息。

下面详细解释这两个概念:


🔍 1. VmSize(Virtual Memory Size)

  • 全称:Virtual Memory Size
  • 单位:kB(千字节)
  • 含义:进程当前使用的虚拟内存总量
  • 包括
    • 可执行代码(text segment)
    • 堆(heap,如 mallocnew 分配)
    • 栈(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)进一步分析。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐