轉載目的,主要是為了理解lVIRT虛擬內存、RES常駐內存、共享內存SHR、SWAP和實際程序應用如何對應的。
在Linux命令行中執行top命令,可以查詢到所有進程使用的VIRT虛擬內存、RES常駐內存和共享內存SHR。
那么,什么是VIRT虛擬內存、RES常駐內存和共享內存SHR?我們編寫的Linux C++程序如何影響它們呢?
查閱資料后,歸納一下。
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后,它將會降下來。
SWAP:
只有當物理內存耗盡時才會使用到,linux的swap原則是盡量使用物理內存。
測試如下:
一)
- #include <iostream>
- int main()
- {
- char * p = new char [1024*1024*512];
- getchar();
- return 0;
- }
top結果如下:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
401 huyiyang 17 0 523m 916 792 S 0.0 0.0 0:00.00 ./main
VIRT包含了new出來的512MB空間,但是RES不包含該空間。即剛new出來的空間,如果沒有使用,會放入SWAP中,並不在內容中真實的分配物理內存。
二)
- #include <iostream>
- int main()
- {
- char * p = new char [1024*1024*512];
- memset(p, 0, 1024*1024*512);
- getchar();
- return 0;
- }
top結果如下:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
32604 huyiyang 17 0 523m 512m 792 S 0.0 26.2 0:00.33 ./main
VIRT包含new出來的512MB空間,RES包含目前使用的memset的512M空間。即new出來的空間被使用后,會真實分配物理內存。
三)
- #include <iostream>
- int main()
- {
- char * p = new char [1024*1024*512];
- memset(p + 1024*1024*128, 0, 1024*1024*128);
- getchar();
- return 0;
- }
top結果如下:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
456 huyiyang 17 0 523m 128m 792 S 0.0 6.6 0:00.07 ./main
VIRT包含new出來的512MB空間,RES包含目前使用的memset的128M空間。即new出來的空間,如果只使用部分,則只分配部分物理內存。
四)
- #include <iostream>
- int main()
- {
- char p[1024*1024*10];
- getchar();
- return 0;
- }
top結果如下:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
544 huyiyang 17 0 21568 884 760 S 0.0 0.0 0:00.00 ./main
沒有使用的棧空間,VIRT會包含(沒有使用的棧空間會在SWAP中)。
五)
- #include <iostream>
- int main()
- {
- char p[1024*1024*10];
- memset(p, 0, 1024*1024*10);
- getchar();
- return 0;
- }
top結果如下:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
561 huyiyang 17 0 21568 10m 760 S 0.0 0.6 0:00.00 ./main
已經使用的棧空間,VIRT和RES都會包含。
六)
- #include <iostream>
- int main()
- {
- char ** pp = new char * [1024];
- for(int i=0;i<1024;i++)
- {
- pp[i] = new char [1024*1024*512];
- memset(pp[i], 0, 1024*1024*512);
- printf("p%d\n", i);
- getchar();
- }
- return 0;
- }
第一個循環時:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ SWAP COMMAND
3627 huyiyang 18 0 523m 512m 836 S 0.0 26.2 0:00.34 10m ./main
第二個循環時:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ SWAP COMMAND
3627 huyiyang 18 0 1035m 1.0g 836 S 0.0 52.4 0:00.69 10m ./main
第三個循環時:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ SWAP COMMAND
3627 huyiyang 18 0 1547m 1.5g 836 S 0.0 78.5 0:01.03 10m ./main
在我的服務器上,當執行到第四個循環時,並且有其他程序占用較大內存的情況下,top結果如下:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ SWAP COMMAND
3427 huyiyang 16 0 2059m 711m 836 S 0.0 36.4 0:01.45 1.3g ./main
出現了swap out的情況。
