Linux内存那些事 -- VSS、RSS、PSS、USS

1、背景

如果一个进程内存消耗太多,那么会导致整个系统内存紧张,而出现OOM等。所以我们经常会需要统计整个系统各个进程内存消耗的情况。一般对一个进程的内存的表示有4种方式:VSS、RSS、PSS、USS,那么什么时候应该用哪种方式统计呢?

我们需要先了解他们的差别:

VSS- Virtual Set Size 虚拟耗用内存(包含共享库占用的全部内存,以及分配但未使用内存)
RSS- Resident Set Size 实际使用物理内存(包含共享库占用的全部内存)
PSS- Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS- Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS

2、例子

2.1 无内存分配的helloworld

我们写一个helloworld程序,仅仅打印点东西出来:

#include <stdio.h>

int main()
{

        printf("======== begin\n");

//      char aa[1048576*2];
//      memset(aa, 0, sizeof(aa));

//      printf("======== end size:%d\n", sizeof(aa));


        while(1)
        {
//              sleep(5);
        }

        return 0;
}

注意:以上循环里我把sleep那一行注释掉了,目的是通过top查看的时候方便看到其结果。

我们编译,运行,然后top看结果:

$ gcc main.c -o mymain 
$ ./mymain &
[1] 9454
$ ======== begin

$ top

top - 09:24:49 up 22:16,  1 user,  load average: 1.62, 1.29, 1.11
Tasks: 160 total,   2 running, 127 sleeping,   0 stopped,   0 zombie
%Cpu(s): 99.7 us,  0.3 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  4039440 total,  1165872 free,   786108 used,  2087460 buff/cache
KiB Swap:   998396 total,   998396 free,        0 used.  2923700 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                                                  
 9454 wjbvb2    20   0    4352    724    656 R 93.4  0.0   0:05.15 mymain  

2.2 有内存分配但未使用的helloworld

我们追加内容到刚才的helloworld程序,分配2M的内存,但不使用它:

扫描二维码关注公众号,回复: 13637077 查看本文章
#include <stdio.h>

int main()
{

        printf("======== begin\n");

        char aa[1048576*2];
//      memset(aa, 0, sizeof(aa));

        printf("======== end size:%d\n", sizeof(aa));


        while(1)
        {
//              sleep(5);
        }

        return 0;
}

我们编译,运行,然后top看结果:

$ gcc main.c -o mymain 
main.c: In function ‘main’:
main.c:11:16: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
         printf("======== end size:%d\n", sizeof(aa));
                ^
$ ./mymain &
[1] 9482
$ ======== begin
======== end size:2097152

$ top

top - 09:30:14 up 22:22,  1 user,  load average: 0.41, 0.92, 1.01
Tasks: 160 total,   3 running, 126 sleeping,   0 stopped,   0 zombie
%Cpu(s):  6.8 us,  0.4 sy,  0.0 ni, 92.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  4039440 total,  1165748 free,   786100 used,  2087592 buff/cache
KiB Swap:   998396 total,   998396 free,        0 used.  2923628 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                                                         
 9482 wjbvb2    20   0    6276    780    716 R 37.5  0.0   0:01.45 mymain

2.3 有内存分配且使用的helloworld

我们追加内容到刚才的helloworld程序,分配2M的内存,且使用它:

#include <stdio.h>

int main()
{

        printf("======== begin\n");

        char aa[1048576*2];
        memset(aa, 0, sizeof(aa));

        printf("======== end size:%d\n", sizeof(aa));


        while(1)
        {
//              sleep(5);
        }

        return 0;
}

我们编译,运行,然后top看结果:

$ gcc main.c -o mymain 
main.c: In function ‘main’:
main.c:9:2: warning: implicit declaration of function ‘memset’ [-Wimplicit-function-declaration]
  memset(aa, 0, sizeof(aa));
  ^
main.c:9:2: warning: incompatible implicit declaration of built-in function ‘memset’
main.c:9:2: note: include ‘<string.h>’ or provide a declaration of ‘memset’
main.c:11:16: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
         printf("======== end size:%d\n", sizeof(aa));
                ^
wjbvb2@wjbvb2:~/study/memory$ ./mymain &
[1] 9508
$ ======== begin
======== end size:2097152

$ top

top - 09:34:59 up 22:27,  1 user,  load average: 0.95, 0.97, 1.00
Tasks: 160 total,   3 running, 126 sleeping,   0 stopped,   0 zombie
%Cpu(s):  7.1 us,  0.4 sy,  0.0 ni, 92.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  4039440 total,  1163764 free,   788100 used,  2087576 buff/cache
KiB Swap:   998396 total,   998396 free,        0 used.  2921716 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                                                     
 9508 wjbvb2    20   0    6284   3036   1160 R 38.9  0.1   0:01.79 mymain  

这里的VIRT就是VSS,RES就是RSS,我们总结如下:

编号 内存分配、使用情况 VSS(单位:4K) RSS(单位:4K)
1 无内存分配 4352 724
2 有分配但未使用 6276 780
3 有分配且使用 6284 3036

由此看:

如果分配了内存,但是未使用的话,会反映到VSS里,但是不会反映到RSS里。

如果分配了内存,而且使用了的话,既会反映到VSS里,也会反映到RSS里。

猜你喜欢

转载自blog.csdn.net/sjwangjinbao/article/details/119477471