自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux進(jìn)程的內(nèi)存使用情況

系統(tǒng) Linux
在linux下,使用top,ps等命令查看進(jìn)程的內(nèi)存使用情況時(shí),經(jīng)??吹絍IRT,RES,SHR等,他們都代表什么意思呢?不同的大小對(duì)進(jìn)程有什么影響呢?這篇文章將來(lái)聊一聊這個(gè)問題。閱讀本篇前建議先閱讀Linux內(nèi)存管理,了解一些Linux下內(nèi)存的基本概念,如什么是anonymous和file backed映射等。

在linux下,使用top,ps等命令查看進(jìn)程的內(nèi)存使用情況時(shí),經(jīng)常看到VIRT,RES,SHR等,他們都代表什么意思呢?不同的大小對(duì)進(jìn)程有什么影響呢?這篇文章將來(lái)聊一聊這個(gè)問題。閱讀本篇前建議先閱讀Linux內(nèi)存管理,了解一些Linux下內(nèi)存的基本概念,如什么是anonymous和file backed映射等。

Linux進(jìn)程的內(nèi)存使用情況

查看進(jìn)程所使用的內(nèi)存

在進(jìn)程的眼里,所有的內(nèi)存都是虛擬內(nèi)存,但是這些虛擬內(nèi)存所對(duì)應(yīng)的物理內(nèi)存是多少呢?正如我們?cè)贚inux內(nèi)存管理中所介紹的那樣,并不是每塊虛擬內(nèi)存都有對(duì)應(yīng)的物理內(nèi)存,可能對(duì)應(yīng)的數(shù)據(jù)在磁盤上的一個(gè)文件中,或者交換空間上的一塊區(qū)域里。一個(gè)進(jìn)程真正的物理內(nèi)存使用情況只有內(nèi)核知道,我們只能通過內(nèi)核開放的一些接口來(lái)獲取這些統(tǒng)計(jì)數(shù)據(jù)。

top

先看看top的輸出(top用到的數(shù)據(jù)來(lái)自于/proc/[pid]/statm),這里只是摘錄了幾條數(shù)據(jù):

  1.  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND 
  2. 2530 root      20   0       0      0      0 S  0.3  0.0   0:02.69 kworker/0:0 
  3. 2714 dev       20   0   41824   3700   3084 R  0.3  0.7   0:00.02 top 
  4. 3008 dev       20   0   22464   5124   3356 S  0.0  1.0   0:00.02 bash  

VIRT:進(jìn)程所使用的虛擬內(nèi)存大小

RES:系統(tǒng)為虛擬內(nèi)存分配的物理內(nèi)存大小,包括file backed和anonymous內(nèi)存,其中anonymous包含了進(jìn)程自己分配和使用的內(nèi)存,以及和別的進(jìn)程通過mmap共享的內(nèi)存;而file backed的內(nèi)存就是指加載可執(zhí)行文件和動(dòng)態(tài)庫(kù)所占的內(nèi)存,以及通過private方式調(diào)用mmap映射文件所使用的內(nèi)存(當(dāng)在內(nèi)存中修改了這部分?jǐn)?shù)據(jù)且沒有寫回文件,那么這部分內(nèi)存就變成了anonymous),這部分內(nèi)存也可能跟別的進(jìn)程共享。

SHR:RES的一部分,表示和別的進(jìn)程共享的內(nèi)存,包括通過mmap共享的內(nèi)存和file backed的內(nèi)存。當(dāng)通過prive方式調(diào)用mmap映射一個(gè)文件時(shí),如果沒有修改文件的內(nèi)容,那么那部分內(nèi)容就是SHR的,一旦修改了文件內(nèi)容且沒有寫回文件,那么這部分內(nèi)存就是anonymous且非SHR的。

%MEM:等于RES/total*100%,這里total指總的物理內(nèi)存大小。

注意:由于SHR可能會(huì)被多個(gè)進(jìn)程所共享,所以系統(tǒng)中所有進(jìn)程的RES加起來(lái)可能會(huì)超過總的物理內(nèi)存數(shù)量,由于同樣的原因,所有進(jìn)程的%MEM總和可能超過100%。

從上面的分析可以看出,VIRT的參考意義不大,它只能反應(yīng)出程序的大小,而RES也不能完全的代表一個(gè)進(jìn)程真正占用的內(nèi)存空間,因?yàn)樗锩孢€包含了SHR的部分,比如三個(gè)bash進(jìn)程共享了一個(gè)libc動(dòng)態(tài)庫(kù),那么libc所占用的內(nèi)存算誰(shuí)的呢?三個(gè)進(jìn)程平分嗎?如果啟動(dòng)一個(gè)bash占用了4M的RES,其中3M是libc占用的,由于三個(gè)進(jìn)程都共享那3M的libc,那么啟動(dòng)3個(gè)bash實(shí)際占用的內(nèi)存將是3*(4-3)+3=6M,但是如果單純的按照RES來(lái)算的話,三個(gè)進(jìn)程就用了12M的空間。所以理解RES和SHR這兩個(gè)數(shù)據(jù)的含義對(duì)我們?cè)谠u(píng)估一臺(tái)服務(wù)器能跑多少個(gè)進(jìn)程時(shí)尤其重要,不要一看到apache的進(jìn)程占用了20M,就認(rèn)為系統(tǒng)能跑的apache進(jìn)程數(shù)就是總的物理內(nèi)存數(shù)除以20M,其實(shí)這20M里面有可能有很大一部分是SHR的。

注意:top命令輸出中的RES和pmap輸出中的RSS是一個(gè)東西。

pmap

上面top命令只是給出了一個(gè)進(jìn)程大概占用了多少的內(nèi)存,而pmap能更詳細(xì)的給出內(nèi)存都是被誰(shuí)占用了。pmap命令輸出的內(nèi)容來(lái)自于/proc/[pid]/maps和/proc/[pid]/smaps這兩個(gè)文件,第一個(gè)文件包含了每段的一個(gè)大概描述,而后一個(gè)文件包含了更詳細(xì)的信息。

這里用pmap看看當(dāng)前bash的內(nèi)存使用情況,:

  1. #這里$$代表當(dāng)前bash的進(jìn)程ID,下面只顯示了部分輸出結(jié)果 
  2. dev@dev:~$ pmap  $$ 
  3. 2805:   bash 
  4. 0000000000400000    976K r-x-- bash 
  5. 00000000006f3000      4K r---- bash 
  6. 00000000006f4000     36K rw--- bash 
  7. 00000000006fd000     24K rw---   [ anon ] 
  8. 0000000000be4000   1544K rw---   [ anon ] 
  9. ...... 
  10. 00007f1fa0e9e000   2912K r---- locale-archive 
  11. 00007f1fa1176000   1792K r-x-- libc-2.23.so 
  12. 00007f1fa1336000   2044K ----- libc-2.23.so 
  13. 00007f1fa1535000     16K r---- libc-2.23.so 
  14. 00007f1fa1539000      8K rw--- libc-2.23.so 
  15. 00007f1fa153b000     16K rw---   [ anon ] 
  16. ...... 
  17. 00007f1fa196c000    152K r-x-- ld-2.23.so 
  18. 00007f1fa1b7e000     28K r--s- gconv-modules.cache 
  19. 00007f1fa1b85000     16K rw---   [ anon ] 
  20. 00007f1fa1b8f000      8K rw---   [ anon ] 
  21. 00007f1fa1b91000      4K r---- ld-2.23.so 
  22. 00007f1fa1b92000      4K rw--- ld-2.23.so 
  23. 00007f1fa1b93000      4K rw---   [ anon ] 
  24. 00007ffde903a000    132K rw---   [ stack ] 
  25. 00007ffde90e4000      8K r----   [ anon ] 
  26. 00007ffde90e6000      8K r-x--   [ anon ] 
  27. ffffffffff600000      4K r-x--   [ anon ] 
  28.  total            22464K  

這里第一列是內(nèi)存的起始地址,第二列是mapping的地址大小,第三列是這段內(nèi)存的訪問權(quán)限,最后一列是mapping到的文件。這里的地址都是虛擬地址,大小也是虛擬地址大小。

這里的輸出有很多的[ anon ]行,表示在磁盤上沒有對(duì)應(yīng)的文件,這些一般都是可執(zhí)行文件或者動(dòng)態(tài)庫(kù)里的bss段。當(dāng)然有對(duì)應(yīng)文件的mapping也有可能是anonymous,比如文件的數(shù)據(jù)段。關(guān)于程序的數(shù)據(jù)段和bss段的介紹請(qǐng)參考elf的相關(guān)資料。

上面可以看到bash、libc-2.23.so等文件出現(xiàn)了多行,但每行的權(quán)限不一樣,這是因?yàn)槊總€(gè)動(dòng)態(tài)庫(kù)或者可執(zhí)行文件里面都分很多段,有只能讀和執(zhí)行的代碼段,有能讀寫的數(shù)據(jù)段,還有比如這一行“00007f1fa153b000 16K rw--- [ anon ]”,就是它上面一行l(wèi)ibc-2.23.so的bss段。

[ stack ]表示進(jìn)程用到的??臻g,而heap在這里看不到,因?yàn)閜map默認(rèn)情況下不單獨(dú)標(biāo)記heap出來(lái),由于heap是anonymous,所以從這里的大小可以推測(cè)出來(lái),heap就是“0000000000be4000 1544K rw--- [ anon ]”。

其實(shí)從上面的結(jié)果根本看不出實(shí)際上每段占用了多少物理內(nèi)存,要想看到RSS,需要使用-X參數(shù),下面看看更詳細(xì)的輸出:

  1. dev@dev:~$ pmap -X $$ 
  2. 2805:   bash 
  3.          Address Perm   Offset Device  Inode  Size  Rss  Pss Referenced Anonymous Shared_Hugetlb Private_Hugetlb Swap SwapPss Locked Mapping 
  4.         00400000 r-xp 00000000  fc:00 390914   976  888  526        888         0              0               0    0       0      0 bash 
  5.         006f3000 r--p 000f3000  fc:00 390914     4    4    4          4         4              0               0    0       0      0 bash 
  6.         006f4000 rw-p 000f4000  fc:00 390914    36   36   36         36        36              0               0    0       0      0 bash 
  7.         006fd000 rw-p 00000000  00:00      0    24   24   24         24        24              0               0    0       0      0 
  8.         00be4000 rw-p 00000000  00:00      0  1544 1544 1544       1544      1544              0               0    0       0      0 [heap] 
  9.     ..... 
  10.     7f1fa0e9e000 r--p 00000000  fc:00 136340  2912  400   83        400         0              0               0    0       0      0 locale-archive 
  11.     7f1fa1176000 r-xp 00000000  fc:00 521726  1792 1512   54       1512         0              0               0    0       0      0 libc-2.23.so 
  12.     7f1fa1336000 ---p 001c0000  fc:00 521726  2044    0    0          0         0              0               0    0       0      0 libc-2.23.so 
  13.     7f1fa1535000 r--p 001bf000  fc:00 521726    16   16   16         16        16              0               0    0       0      0 libc-2.23.so 
  14.     7f1fa1539000 rw-p 001c3000  fc:00 521726     8    8    8          8         8              0               0    0       0      0 libc-2.23.so 
  15.     7f1fa153b000 rw-p 00000000  00:00      0    16   12   12         12        12              0               0    0       0      0 
  16.     ...... 
  17.     7f1fa196c000 r-xp 00000000  fc:00 521702   152  144    4        144         0              0               0    0       0      0 ld-2.23.so 
  18.     7f1fa1b7e000 r--s 00000000  fc:00 132738    28   28    9         28         0              0               0    0       0      0 gconv-modules.cache 
  19.     7f1fa1b85000 rw-p 00000000  00:00      0    16   16   16         16        16              0               0    0       0      0 
  20.     7f1fa1b8f000 rw-p 00000000  00:00      0     8    8    8          8         8              0               0    0       0      0 
  21.     7f1fa1b91000 r--p 00025000  fc:00 521702     4    4    4          4         4              0               0    0       0      0 ld-2.23.so 
  22.     7f1fa1b92000 rw-p 00026000  fc:00 521702     4    4    4          4         4              0               0    0       0      0 ld-2.23.so 
  23.     7f1fa1b93000 rw-p 00000000  00:00      0     4    4    4          4         4              0               0    0       0      0 
  24.     7ffde903a000 rw-p 00000000  00:00      0   136   24   24         24        24              0               0    0       0      0 [stack] 
  25.     7ffde90e4000 r--p 00000000  00:00      0     8    0    0          0         0              0               0    0       0      0 [vvar] 
  26.     7ffde90e6000 r-xp 00000000  00:00      0     8    4    0          4         0              0               0    0       0      0 [vdso] 
  27. ffffffffff600000 r-xp 00000000  00:00      0     4    0    0          0         0              0               0    0       0      0 [vsyscall] 
  28.                                              ===== ==== ==== ========== ========= ============== =============== ==== ======= ====== 
  29.                                              22468 5084 2578       5084      1764              0               0    0       0      0 KB  
  • 權(quán)限字段多了一個(gè)s和p的標(biāo)記,s表示是和別人共享的內(nèi)存空間,讀寫會(huì)影響到其他進(jìn)程,而p表示這是自己私有的內(nèi)存空間,讀寫這部分內(nèi)存不會(huì)對(duì)其他進(jìn)程造成影響。
  • 輸出標(biāo)示出了[heap]段,并且也說明了后面幾個(gè)[anon]代表的什么意思(vvar,vdso,vsyscall都是映射到內(nèi)核的特殊段),mapping字段為空的都是上一行mapping文件里面的bss段(可是gconv-modules.cache后面有兩行anonymous mapping,可能跟共享內(nèi)存有關(guān)系,沒有深究)。
  • Anonymous列標(biāo)示出了哪些是并且有多少是Anonymous方式映射的物理內(nèi)存,其大小小于等于RSS
  • RSS列表示實(shí)際占用的物理內(nèi)存大小

top命令輸出的SHR內(nèi)存

最后來(lái)看看top命令輸出的SHR到底由pmap的哪些輸出構(gòu)成

  1. dev@dev:~$ pmap -d $$ 
  2. 3108:   bash 
  3. Address           Kbytes Mode  Offset           Device    Mapping 
  4. 0000000000400000     976 r-x-- 0000000000000000 0fc:00000 bash 
  5. 00000000006f3000       4 r---- 00000000000f3000 0fc:00000 bash 
  6. 00000000006f4000      36 rw--- 00000000000f4000 0fc:00000 bash 
  7. 00000000006fd000      24 rw--- 0000000000000000 000:00000   [ anon ] 
  8. 0000000000c23000    1544 rw--- 0000000000000000 000:00000   [ anon ] 
  9. ...... 
  10. 00007f53af18e000      16 rw--- 0000000000000000 000:00000   [ anon ] 
  11. 00007f53af198000       8 rw--- 0000000000000000 000:00000   [ anon ] 
  12. 00007f53af19a000       4 r---- 0000000000025000 0fc:00000 ld-2.23.so 
  13. 00007f53af19b000       4 rw--- 0000000000026000 0fc:00000 ld-2.23.so 
  14. 00007f53af19c000       4 rw--- 0000000000000000 000:00000   [ anon ] 
  15. 00007ffc5a94b000     132 rw--- 0000000000000000 000:00000   [ stack ] 
  16. 00007ffc5a9b7000       8 r---- 0000000000000000 000:00000   [ anon ] 
  17. 00007ffc5a9b9000       8 r-x-- 0000000000000000 000:00000   [ anon ] 
  18. ffffffffff600000       4 r-x-- 0000000000000000 000:00000   [ anon ] 
  19. mapped: 22464K    writeable/private: 1848K    shared: 28K 
  20.  
  21. dev@dev:~$ top -p $$ 
  22.   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND 
  23.  3108 dev       20   0   22464   5028   3264 S  0.0  1.0   0:00.02 bash 

從上面的輸出可看出SHR ≈ RES - writeable/private,其中writeable/private主要包含stack和heap以及可執(zhí)行文件和動(dòng)態(tài)庫(kù)的data和bss段,而stack+heap=1544+132=1675,這已經(jīng)占了絕大部分,從而data和bss段之類的基本上可以忽略了,所以一般情況下,SHR ≈ RES - [heap] - [stack],由于stack一般都比較小,上面的等式可以進(jìn)一步約等于:SHR ≈ RES - [heap]。

總結(jié)

top命令能看到一個(gè)進(jìn)程占用的虛擬內(nèi)存空間、物理內(nèi)存空間以及和別的進(jìn)程共享的物理內(nèi)存空間,這里共享的空間包括通過mmap共享的內(nèi)存以及共享的可執(zhí)行文件以及動(dòng)態(tài)庫(kù)。而mmap命令能看到更詳細(xì)的信息,比如可執(zhí)行文件和它所鏈接的動(dòng)態(tài)庫(kù)大小,以及物理內(nèi)存都是被哪些段給占用了。

進(jìn)程占用的虛擬地址空間大小跟程序的規(guī)模有關(guān),除了stack和heap段,其他段的大小基本上都是固定的,并且在程序鏈接的時(shí)候就已經(jīng)確定了,所以基本上只要關(guān)注stack和heap段就可以了,由于stack相對(duì)heap來(lái)說很小,所以只要沒什么stack異常,只需要關(guān)注heap。

在實(shí)際的工作過程中,其實(shí)我們更關(guān)心的是RSS用了多少,都被誰(shuí)用了,簡(jiǎn)單點(diǎn)說,如果我們沒有同時(shí)啟動(dòng)多個(gè)進(jìn)程(同一個(gè)程序),RSS就是一個(gè)很好的實(shí)際物理內(nèi)存使用參考值,但如果是像apache那樣同時(shí)跑很多個(gè)進(jìn)程,那么RSS減去SHR所占用的空間就是一個(gè)很好的實(shí)際物理內(nèi)存占用參考值,當(dāng)然這都是大概估算值。

要想精確評(píng)估一個(gè)進(jìn)程到底占了多少內(nèi)存,還是很難的,需要對(duì)進(jìn)程的每個(gè)段有深入的理解,尤其是SHR部分都有哪些進(jìn)程在一起共享,不過現(xiàn)在服務(wù)器上的內(nèi)存都是以G為單位的,所以一般情況下大概的估算一下加上合理的測(cè)試就能滿足我們的需求了。

責(zé)任編輯:龐桂玉 來(lái)源: segmentfault
相關(guān)推薦

2010-06-02 11:06:15

Linux 內(nèi)存監(jiān)控

2020-02-04 13:50:09

Linux進(jìn)程內(nèi)存使用

2010-02-03 17:16:58

Linux內(nèi)存使用

2023-08-21 14:18:48

操作系統(tǒng)Linux

2022-09-26 09:44:10

Linux

2022-07-13 14:26:26

Linux

2020-02-10 19:50:08

Linux內(nèi)存使用命令

2019-06-24 08:53:01

Bash腳本Linux系統(tǒng)運(yùn)維

2010-06-02 12:47:12

Linux 內(nèi)存監(jiān)控

2020-06-17 14:10:01

Python內(nèi)存程序

2022-04-07 06:04:00

NetHogs開源網(wǎng)絡(luò)工具

2010-10-14 16:10:28

MySQL排序

2010-09-26 12:45:29

2009-06-16 09:18:26

Linux系統(tǒng)管理系統(tǒng)資源

2009-12-14 17:25:20

Linux操作系統(tǒng)

2014-04-24 16:26:31

UbuntuUbuntu 磁盤Linux基礎(chǔ)

2013-07-23 06:56:12

Android內(nèi)存機(jī)制APP內(nèi)存使用情況Android開發(fā)學(xué)習(xí)

2015-11-09 15:32:34

TorTor網(wǎng)絡(luò)隱私網(wǎng)絡(luò)

2009-07-09 18:03:25

tomcatJVM內(nèi)存

2009-10-21 12:42:20

Linux系統(tǒng)資源操作系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)