使用ps命令查看进程的内存使用情况时,有3列输出,分别是%MEM、VSZ和RSS,其中VSZ全称为Virtual Memory Size,RSS全称为Resident Set Size,而MEM则是RSS占全部内存的百分比。
为什么要用两列VSZ和RSS表示进程的内存使用量呢?从它们两个名称上,就可以窥见一二。VSZ表示虚拟内存大小,RSS表示驻留物理内存的内存大小。前者VSZ并没有真正占用物理内存,只是划分了地址空间,并没有建立虚拟地址与物理内存的映射——这也是Linux常用的优化方法,如COW,都是在真正需要的时候,才分配资源。所以当查看哪个进程占用内存过多时,我们只要查看RSS列,而非VSZ。因为某些服务经常一启动就申请了大量的内存,但实际并没有使用,代表服务如java虚拟机。
下图是一个来自阿里ECS的截图:
其中红线指向的第5列和第6列分别为VSZ和RSS,其值分别为2G+和74M+。
接下来,我们自己编码测试VSZ和RSS。
在这个简单的代码中,函数alloc_mem用于循环512次,每次申请1M的内存,一共申请512M内存。执行的时候,没有任何参数时,则只申请内存,但不对该内存做任何写入操作,当参数个数大于等于一个时,通过memset向内存填充0值。
第一次执行的时候,不带任何参数,ps输出如下:
VSZ的大小是539M,而RSS只有3M。可见,尽管应用申请了内存,但因为没有使用,实际上并没有占用什么资源。
第二次执行的时候,使用一个参数,ps输出如下:
这时,VSZ大小不变,仍然是539M,而RSS则增加到了527M。由于使用memset对申请的内存执行了写入操作,所以内核必须要真正分配给该应用物理内存了。
PS: 测试代码位于https://github.com/gfreewind/LinuxDetails/blob/master/mem/1.vsz_and_rss/vsz_and_rss.cpp