linux top命令看到的實存(RES)與虛存(VIRT)分析

linux top命令看到的實存(RES)與虛存(VIRT)分析

 近期在公司中解決程序使用的內存高問題,將一部分之前無法回收的內存進行了回收,實現降內存效果(降實存)。

在統計效果時, QA問是統計RES(實存)還是VIRT(虛存)。

在網上學習看了一些博客,這裏自己總結一下RES和VIRT的區別。

1. 概念

VIRT:

1

2

3

1、進程“需要的”虛擬內存大小,包括進程使用的庫、代碼、數據,以及malloc、new分配的堆空間和分配的棧空間等;

2、假如進程新申請10MB的內存,但實際只使用了1MB,那麼它會增長10MB,而不是實際的1MB使用量。

3、VIRT = SWAP + RES

 RES:

1

2

3

4

5

1、進程當前使用的內存大小,包括使用中的malloc、new分配的堆空間和分配的棧空間,但不包括swap out量;

2、包含其他進程的共享;

3、如果申請10MB的內存,實際使用1MB,它只增長1MB,與VIRT相反;

4、關於庫佔用內存的情況,它只統計加載的庫文件所佔內存大小。

5、RES = CODE + DATA

 SHR:

1

2

3

4

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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章