1. 在linux下,檢視一個運作中的程式, 占用了多少記憶體, 一般的指令有
(1). ps aux:
其中 VSZ(或VSS)列 表示,程式占用了多少虛拟記憶體。
RSS列 表示, 程式占用了多少實體記憶體。
虛拟記憶體可以不用考慮,它并不占用實際實體記憶體。
#ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 19360 1528 ? Ss Jul18 0:00 /sbin/init
root 2 0.0 0.0 0 0 ? S Jul18 0:01 [kthreadd]
root 3 0.0 0.0 0 0 ? S Jul18 0:00 [migration/0]
root 4 0.0 0.0 0 0 ? S Jul18 74:00 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S Jul18 0:00 [migration/0]
root 6 0.0 0.0 0 0 ? S Jul18 0:09 [watchdog/0]
root 7 0.0 0.0 0 0 ? S Jul18 0:15 [migration/1]
root 8 0.0 0.0 0 0 ? S Jul18 0:00 [migration/1]
root 9 0.0 0.0 0 0 ? S Jul18 42:05 [ksoftirqd/1]
root 10 0.0 0.0 0 0 ? S Jul18 0:07 [watchdog/1]
root 11 0.0 0.0 0 0 ? S Jul18 0:02 [migration/2]
root 12 0.0 0.0 0 0 ? S Jul18 0:00 [migration/2]
root 13 0.0 0.0 0 0 ? S Jul18 18:26 [ksoftirqd/2]
root 14 0.0 0.0 0 0 ? S Jul18 0:06 [watchdog/2]
(2). top 指令也可以
其中 VIRT(或VSS)列 表示,程式占用了多少虛拟記憶體。 同 ps aux 中的 VSZ列
RES列 表示, 程式占用了多少實體記憶體。同 ps aux 中的RSS列
#top
top - 19:41:09 up 97 days, 10:44, 1 user, load average: 0.04, 0.01, 0.00
Tasks: 424 total, 1 running, 423 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni, 99.9%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 16333244k total, 5963824k used, 10369420k free, 536076k buffers
Swap: 10485752k total, 0k used, 10485752k free, 1859516k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2762 jbossuse 20 0 17.4g 3.0g 35m S 0.3 19.5 1:48.00 java
12789 root 20 0 15304 1552 972 R 0.3 0.0 0:00.03 top
1 root 20 0 19360 1528 1216 S 0.0 0.0 0:00.99 init
2 root 20 0 0 0 0 S 0.0 0.0 0:01.37 kthreadd
2.在linux下, 檢視目前系統占用了多少記憶體, 一般的指令是 free
其中, free就是系統還有多少記憶體可以使用。
但由于 linux 系統對記憶體使用有一個原則, 就是, 記憶體是寶貴的, 能使用多少就使用多少。 是以, linux會把已經調用過的包緩存起來,放在記憶體裡。
這樣,實際上,可以使用的記憶體,就可以了解為, free+buffers+cached
3.當你了解完這些指令以後, 再去使用ps aux 指令去檢視的時候, 會發現一個奇怪的現象。
所有的 RSS 列的資料,加起來, 比實體記憶體的數要大很多。
比如, 實體記憶體為2G, 而RSS列的資料加起來,可能有5個G之多, 這是怎麼回事了?
這是因為RSS列的值騙了我們。
linux的記憶體機制是這樣的:
在運作一個程式時, linux會調用該程式依賴的連結庫, 如lib.xx.so。 首先看該連結庫是否被映射進記憶體中,如果沒有被映射,則将代碼段與資料段映射到記憶體中,否則隻是将其加入程序的位址空間。
這樣,當N個程式,依賴到lib.xx.so的時候, 實際上,記憶體中隻有一個lib.xx.so ,而不是N個。
而RSS在顯示一個程式占用的實際實體記憶體時, 将lib.xx.so也算了進來。
比如, X程式, 本身占用記憶體為5M, lib.xx.so 占用記憶體2M,lib.xx.so被N個程式共享依賴。 則RSS顯示為,X程式運作,占用記憶體為7M。 實際上, X程式占用了5M空間。 多餘的2m被讨入到RSS中了。
當你在用ps aux顯示記憶體占用情況時, N個共享依賴lib.xx.so的N個程式,都把這2m空間,算在自己的RSS中了, 這樣RSS的sum值,就比實際實體記憶體多了。
當然, linux的記憶體使用機制很複雜, 不是一句兩句能說清楚的。這裡隻是簡單的說明了一下, ps aux中的RSS值, 并不能真實反映實體記憶體的使用情況。
4. 如果檢視更詳細的記憶體使用情況, 可用以下幾種方法, 或者幾種方法結合使用:
這幾種方法,都需要root賬戶的權限
(1). pmap -d $pid
$pid 是正在運作的程式的pid
502 2762 2682 0 11:54 ? 00:01:48 /opt/wildfly/java64/jdk1.7.0_25/bin/java -D[Standalone] -server -Xms4096m -Xmx8192m -XX:MaxPermSize=512m -Djava.net.preferIPv4Stack=true -Dfile.......
(2). cat /proc/$pid/smaps
smaps的資料比較詳細,可簡單的歸納一下,歸納的指令如下:
cat /proc/$pid/smaps | awk '/Size|Rss|Pss|Shared|Private|Referenced|Swap/{val_name=gensub(/([a-zA-Z_]*).*/,"\\1",1,$1); list[val_name]+=$2; }END{for(val in list)print val,list[val];}'
(3). cat /proc/$pid/maps
(4). cat /proc/$pid/statm
# cat /proc/2762/statm
4569543 795414 9116 1 0 4494492 0
輸出解釋
第一列 size:任務虛拟位址空間大小
第二列 Resident:正在使用的實體記憶體大小
第三列 Shared:共享頁數
第四列 Trs:程式所擁有的可執行虛拟記憶體大小
第五列 Lrs:被映像倒任務的虛拟記憶體空間的庫的大小
第六列 Drs:程式資料段和使用者态的棧的大小
第七列 dt:髒頁數量
關于軟體性能分析調優,可以加微信号yq597365581或者微信号hqh345932,進入專業的性能分析調優群進行交流溝通。

作者的原創文章,轉載須注明出處。原創文章歸作者所有,歡迎轉載,但是保留版權。對于轉載了部落客的原創文章,不标注出處的,作者将依法追究版權,請尊重作者的成果。