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 MemPID 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的内存,但不使用它:
#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 MemPID 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 MemPID 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里。
文章评论