TA的每日心情 | 开心 2021-12-13 21:45 |
---|
签到天数: 15 天 [LV.4]偶尔看看III
|
近期在公司中解决程序使用的内存高问题,将一部分之前无法回收的内存进行了回收,实现降内存效果(降实存)。
在统计效果时, QA问是统计RES(实存)还是VIRT(虚存)。
在网上学习看了一些博客,这里自己总结一下RES和VIRT的区别。
1. 概念
VIRT:
- 1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据,以及malloc、new分配的堆空间和分配的栈空间等;
- 2、假如进程新申请10MB的内存,但实际只使用了1MB,那么它会增长10MB,而不是实际的1MB使用量。
- 3、VIRT = SWAP + RES
复制代码
RES:
- 1、进程当前使用的内存大小,包括使用中的malloc、new分配的堆空间和分配的栈空间,但不包括swap out量;
- 2、包含其他进程的共享;
- 3、如果申请10MB的内存,实际使用1MB,它只增长1MB,与VIRT相反;
- 4、关于库占用内存的情况,它只统计加载的库文件所占内存大小。
- 5、RES = CODE + DATA
复制代码
SHR:
- 1、除了自身进程的共享内存,也包括其他进程的共享内存;
- 2、虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小;
- 3、计算某个进程所占的物理内存大小公式:RES – SHR;
- 4、swap out后,它将会降下来。
复制代码
2. 测试
(1) 使用堆分配内存, 进行测试:
- 1 #include <iostream>
- 2 #include <stdio.h>
- 3 #include <string.h>
- 4
- 5 int main()
- 6 {
- 7 int test = 0;
- 8 //分配512M, 未使用
- 9 char * p = new char [1024*1024*512];
- 10 scanf("%d", &test); //等待输入
- 11
- 12 //使用10M
- 13 memset(p, 0, 1024 * 1024 * 10);
- 14 scanf("%d", &test); //等待输入
- 15
- 16 //使用50M
- 17 memset(p, 0, 1024 * 1024 * 50);
- 18 scanf("%d", &test); //等待输入
- 19 delete [] p;
- 20 return 0;
- 21 }
复制代码
执行:
new 512M后,VIRT/RES
使用10M后,VIRT/RES
使用50M后,VIRT/RES
(2) 使用栈分配内存进行测试:
- 1 #include <iostream>
- 2 #include <stdio.h>
- 3 #include <string.h>
- 4
- 5 int main()
- 6 {
- 7 int test = 0;
- 8 //20M栈, 未使用
- 9 char p[1024*1024*20];
- 10 scanf("%d", &test); //等待输入
- 11
- 12 //使用10M
- 13 memset(p, 0, 1024 * 1024 * 10);
- 14 scanf("%d", &test); //等待输入
- 15 return 0;
- 16 }
复制代码
执行:
栈上申请20M
使用10M
3. 总结
堆、栈分配的内存,如果没有使用是不会占用实存的,只会记录到虚存。
如果程序占用实存比较多,说明程序申请内存多,实际使用的空间也多。
如果程序占用虚存比较多,说明程序申请来很多空间,但是没有使用。
工作中,遇到过有的程序虚存300G+, 实存只有不到15G。
参考:
1. https://www.cnblogs.com/zmlctt/p/3987181.HTML
2. https://blog.csdn.net/huyiyang2010/article/details/7815491 |
|