Linux中VSZ和RSS有什么区别?进程内存指标详解

来源:微信开发网作者:天穹小白头衔:草根站长
导读:本期聚焦于天穹小白创作的《Linux中VSZ和RSS有什么区别?进程内存指标详解》,敬请观看详情。进程内存占用到底该怎么看。在top或ps输出里,VSZ和RSS常常让人混淆。VSZ表示进程虚拟地址空间的总大小,包含未分配物理内存的映射区域、共享库和交换出去的部分。RSS是常驻内存集,只统计实际驻留在物理内存中的页面,不含被换出磁盘的部分。两者差值过大往往说明进程申请了大量虚拟内存却未真正使用,或者大量共享库被多个进程映射。理解这两个指标对排查内存泄漏、评估容器内存限制至关重要,不能单看其中一个数值下结论。

Linux中VSZ和RSS有什么区别?进程内存指标详解

Linux中VSZ和RSS有什么区别?进程内存指标详解

在Linux系统中,当我们使用pstop等工具观察进程状态时,经常会看到VSZRSS这两个内存相关的字段。它们都用来描述进程消耗的内存,但统计口径完全不同。很多初学者甚至有一定经验的开发者,都容易混淆这两个指标,导致在排查内存问题时做出错误判断。搞清楚二者的差异,是分析内存使用、定位泄漏和评估资源限制的基础。本文将从概念入手,结合实际场景和代码示例,带你彻底理解VSZ和RSS的区别。


一、VSZ与RSS的基本概念

VSZ:虚拟内存大小

VSZ是Virtual Memory Size(虚拟内存大小)的缩写。它代表进程所能访问的整个虚拟地址空间的总字节数,包括程序代码、堆、栈、内存映射文件,以及已经申请但还未真正映射到物理内存的部分。Linux采用虚拟内存机制,每个进程都拥有独立的虚拟地址空间,进程申请内存时通常只是扩展了虚拟地址空间,并不会立刻分配物理页。换句话说,VSZ反映的是进程“画了多大的一张饼”,而不是实际吃掉了多少。

举个例子,一个程序启动时通过malloc(1GB)申请了1GB的堆内存,但只实际使用了其中的10MB。此时VSZ会增加1GB,而RSS只会增加10MB左右。这并不意味着系统浪费了内存,而是虚拟内存机制带来的灵活性——进程可以预先保留大片地址空间,等到真正需要使用时才通过缺页中断分配物理内存。

RSS:常驻内存集

RSS是Resident Set Size(常驻内存集)的缩写。它统计的是该进程当前实际驻留在物理内存中的页面总大小。这些页面正被CPU直接访问,没有被交换(swap)到磁盘。需要注意的是,RSS会包含进程使用的共享库内存,如果多个进程共用同一个so文件,这部分物理内存会被每个进程的RSS重复计算。例如,系统中有100个进程都使用了libc.so,那么每个进程的RSS都会计入libc.so占用的那几MB内存,但实际上物理内存中只有一份libc.so的副本。

RSS才是真正反映进程当前占用物理内存的指标,但它并不是精确的“独占”内存量。由于共享库和写时复制(Copy-on-Write)机制的存在,RSS往往会高估进程对物理内存的独占使用。


二、为什么VSZ和RSS数值往往相差很大

虚拟内存的惰性分配

很多初学者看到某个进程的VSZ是2GB,而RSS只有200MB,会误以为系统有内存浪费。其实这是因为进程启动时就通过动态链接器映射了大量共享库,同时可能用mmap预留了很大的缓冲区,但绝大多数虚拟页尚未触发缺页中断,也就没有对应物理内存。Linux的内存分配策略是“按需分配”——只有在进程实际访问某虚拟地址时,内核才会分配物理页并建立映射关系。

例如,一个Java虚拟机(JVM)启动时通常会预留较大的堆空间(通过-Xms和-Xmx参数),但初始阶段堆内存大多未被使用,因此VSZ会显示很大的数值,而RSS相对较小。随着程序运行逐渐分配对象,RSS才会慢慢增长。如果RSS一直远小于VSZ,并不一定代表异常,反而可能是正常的内存预留行为。

共享库与写时复制的影响

另一种常见情况是进程调用了fork()之后,子进程共享父进程的内存页,此时双方RSS都显示共享部分,但物理内存只有一份。当一方写入时产生写时复制(COW),RSS才会真正分化。因此单纯把系统中所有进程的RSS相加,会严重高估实际物理内存占用。这也是为什么free命令看到的“used”内存远小于各进程RSS之和的原因。

此外,动态链接库(.so文件)被多个进程共享时,每个进程的RSS都计入了该库的大小,但物理内存中只有一份。例如,一个大小为5MB的libssl.so被50个进程使用,每个进程RSS中都包含这5MB,但物理内存实际只消耗了5MB。如果据此认为每个进程都独占5MB,就会得出250MB的错误结论。

实际对比示例

我们可以用ps命令直观对比VSZ和RSS:

# 查看指定进程的VSZ和RSS,单位KB
ps -o pid,vsz,rss,comm -p 1234

# 输出类似
#   PID    VSZ   RSS COMMAND
#  1234 2048000 204800 myapp

上面输出中VSZ约为2GB,RSS约为200MB,说明进程虚拟空间大但物理占用小。若RSS长期接近VSZ且持续增长,就要警惕内存泄漏。反之,如果VSZ很大而RSS很小,通常属于正常现象,不必过度担忧。


三、在内存排查中的实际应用

容器环境中的监控

在容器环境里,像Docker默认用RSS相关的cgroup内存限制来杀进程,而不是VSZ。如果只盯VSZ,会以为容器远远没到上限;实际上RSS超了就会被OOM Killer终止。因此写监控脚本时应优先采集RSS,或读取cgroup的memory.stat文件中的rss字段。

例如,一个Docker容器的内存限制设置为512MB,容器内进程的VSZ可能达到2GB,但RSS只有400MB,看起来还在安全范围内。然而如果RSS突然飙升到510MB,就可能触发OOM。此时如果只看VSZ,根本意识不到危险。所以对于容器化部署,务必以RSS(或cgroup中的memory.usage_in_bytes)作为主要监控指标。

内存泄漏定位

排查内存泄漏时,可以间隔采样RSS曲线。如果VSZ和RSS同步上涨且RSS不回落,基本确认堆或匿名映射未释放。而若VSZ暴涨RSS不变,多半是预留虚拟空间过多,不一定影响物理内存,但可能触及地址空间限制(如32位程序3GB天花板)。例如,一个32位进程的虚拟地址空间最多4GB,其中用户空间通常只有3GB。如果VSZ接近3GB而RSS很小,程序可能很快因为无法再分配虚拟地址而崩溃,即使物理内存还很充裕。

在实际工作中,我曾遇到过这样一个案例:一个后台服务每天定时执行大量数据处理,每次处理前都会malloc一块巨大的缓冲区,处理完后却没有及时free。结果VSZ和RSS都随时间线性增长,直到触发OOM。通过监控RSS的增长速率,我们很快定位到了泄漏点。相反,另一个服务频繁调用mmap映射文件但不访问,导致VSZ迅速膨胀,但RSS几乎不变,后来通过限制虚拟地址空间大小解决了问题。

通过代码获取自身内存信息

在C程序中,可以解析/proc/self/statm拿到页数,再乘页面大小,从而获取当前进程的VSZ和RSS。这种方法比在shell里调用ps更高效,也便于嵌入服务做自检。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    long page = sysconf(_SC_PAGESIZE);
    FILE *fp = fopen("/proc/self/statm", "r");
    if (!fp) return 1;
    long total, resident;
    // statm第一列为总页数,第二列为常驻页数
    fscanf(fp, "%ld %ld", &total, &resident);
    fclose(fp);
    printf("VSZ: %ld KB\n", total * page / 1024);
    printf("RSS: %ld KB\n", resident * page / 1024);
    return 0;
}

该程序读取内核暴露的statm文件,第一列乘以页大小即虚拟内存,第二列即常驻集。相比在shell里调ps,这种方式方便嵌入服务做自检,例如在健康检查接口中输出当前内存占用,便于监控系统采集。


四、常见误区与总结

RSS并非独占内存

有人以为RSS就是进程独占的物理内存,这是错的。如前所述,共享库和COW页会让RSS包含非独占部分。若要算进程真实独占量,应结合PSS(Proportional Set Size,按比例占用物理内存)来看。PSS会将共享库的大小按进程数量均摊,例如一个5MB的共享库被5个进程使用,每个进程的PSS中只计入1MB。不过PSS不在ps默认输出,需要借助smem工具或读取/proc/[pid]/smaps手动计算。

总结:VSZ vs RSS

指标

含义

典型用途

VSZ

虚拟内存大小(申请的地址空间总量)

评估地址空间使用情况、检测虚拟内存泄漏、32位程序地址空间限制

RSS

常驻内存集(实际占用的物理内存)

监控物理内存压力、容器OOM判断、定位内存泄漏

总体来看,VSZ告诉你进程“要了多少地”,RSS告诉你“盖了多少房”。评估物理资源看RSS,分析地址空间布局或泄漏趋势时参考VSZ。二者配合,才能对Linux进程内存有准确判断。

最后提醒一点:在排查内存问题时,不要孤立地看单个进程的VSZ或RSS,而要结合系统整体内存使用情况、共享库加载情况以及cgroup限制来综合判断。例如,当你在服务器上运行一个测试站点www.ippipp.com时,如果发现该站点对应的Nginx进程RSS异常增长,不妨先检查是否开启了过多的worker连接,或者是否存在未释放的缓存。掌握VSZ和RSS的本质区别,能让你在面对复杂的内存问题时更加游刃有余。

LinuxVSZRSS修改时间:2026-08-23 06:42:40

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。