近期在公司中解決程序使用的內存高問題,將一部分之前無法回收的內存進行了回收,實現降內存效果(降實存)。
在統計效果時, 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