linux的used 内存去向,Linux Used内存储器到底哪里去了
原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明: 轉(zhuǎn)載自系統(tǒng)技術(shù)非業(yè)余研究
本文鏈接地址: Linux Used內(nèi)存到底哪里去了?
前幾天 純上 同學(xué)問(wèn)了一個(gè)問(wèn)題:
我ps aux看到的RSS內(nèi)存只有不到30M,但是free看到內(nèi)存卻已經(jīng)使用了7,8G了,已經(jīng)開(kāi)始swap了,請(qǐng)問(wèn)ps aux的實(shí)際物理內(nèi)存統(tǒng)計(jì)是不是漏了哪些內(nèi)存沒(méi)算?我有什么辦法確定free中used的內(nèi)存都去哪兒了呢?
這個(gè)問(wèn)題不止一個(gè)同學(xué)遇到過(guò)了,之前子嘉同學(xué)也遇到這個(gè)問(wèn)題,內(nèi)存的計(jì)算總是一個(gè)迷糊賬。 我們今天來(lái)把它算個(gè)清楚下!
通常我們是這樣看內(nèi)存的剩余情況的:
view source
print?
$free -m
total?????? usedfree shared
buffers???? cached
Mem:???????? 48262?????? 7913
40349????????? 0???????? 14??????? 267
-/+ buffers/cache:?????? 7631
40631
Swap:???????? 2047??????? 336
1711
那么這個(gè)信息是如何解讀的呢,以下這個(gè)圖解釋的挺清楚的!
補(bǔ)充(不少人反映圖不清晰,請(qǐng)參考:http://www.redbooks.ibm.com/redpapers/pdfs/redp4285.pdf P46-47)
上面的情況下我們總的內(nèi)存有48262M,用掉了7913M。 其中buffer+cache總共14+267=281M, 由于這種類型的內(nèi)存是可以回收的,雖然我們用掉了7913M,但是實(shí)際上我們?nèi)绻麑?shí)在需要的話,這部分buffer/cache內(nèi)存是可以放出來(lái)的。
我們來(lái)演示下:
view source
print?
$sudo sysctl
vm.drop_caches=3
vm.drop_caches = 3
$free -m
total?????? usedfree shared
buffers???? cached
Mem:???????? 48262?????? 7676
40586????????? 0????????? 3???????? 41
-/+ buffers/cache:?????? 7631
40631
Swap:???????? 2047??????? 336
1711
我們把buffer/cache大部分都清除干凈了,只用了44M,所以我們這次used的空間是7676M。
到現(xiàn)在我們比較清楚幾個(gè)概念:
1. 總的內(nèi)存多少
2. buffer/cache內(nèi)存可以釋放的。
3. used的內(nèi)存的概率。
即使是這樣我們還是要繼續(xù)追查下used的空間(7637M)到底用到哪里去了?
這里首先我們來(lái)介紹下nmon這個(gè)工具,它對(duì)內(nèi)存的使用顯示比較直觀。
使用的內(nèi)存的去向我們很自然的就想到操作系統(tǒng)系統(tǒng)上的各種進(jìn)程需要消耗各種內(nèi)存,我們透過(guò)top工具來(lái)看下:
通常我們會(huì)看進(jìn)程的RES這一項(xiàng),這項(xiàng)到底是什么意思呢?這個(gè)數(shù)字從哪里出來(lái)的呢? 通過(guò)strace對(duì)top和nmon的追蹤和結(jié)合源碼,我們確定這個(gè)值是從/proc/PID/statm的第二個(gè)字段讀取出來(lái)的.
那這個(gè)字段什么意思呢?
man proc或者h(yuǎn)ttp://www.kernel.org/doc/man-pages/online/pages/man5/proc.5.html 會(huì)詳細(xì)的解釋/proc/下的文件的具體意思,我們摘抄下:
/proc/[pid]/statm
Provides information about memory usage, measured in pages. The
columns are:
size total program size
(same as VmSize in /proc/[pid]/status)
resident resident set size
(same as VmRSS in /proc/[pid]/status)
share shared pages (from shared mappings)
text text (code)
lib library (unused in Linux 2.6)
data data + stack
dt dirty pages (unused in Linux 2.6)
resident set size 也就是每個(gè)進(jìn)程用了具體的多少頁(yè)的內(nèi)存。由于linux系統(tǒng)采用的是虛擬內(nèi)存,進(jìn)程的代碼,庫(kù),堆和棧使用的內(nèi)存都會(huì)消耗內(nèi)存,但是申請(qǐng)出來(lái)的內(nèi)存,只要沒(méi)真正touch過(guò),是不算的,因?yàn)闆](méi)有真正為之分配物理頁(yè)面。
我們實(shí)際進(jìn)程使用的物理頁(yè)面應(yīng)該用resident set size來(lái)算的,遍歷所有的進(jìn)程,就可以知道所有的所有的進(jìn)程使用的內(nèi)存。
我們來(lái)實(shí)驗(yàn)下RSS的使用情況:
view source
print?
$cat RSS.sh
#/bin/bash
for PROCin `ls /proc/|grep "^[0-9]"`
do
if [ -f /proc/$PROC/statm
];then
TEP=`cat /proc/$PROC/statm |awk '{print
($2)}'`
RSS=`expr $RSS + $TEP`
fi
done
RSS=`expr $RSS \* 4`
echo $RSS"KB"
$ ./RSS.sh
7024692KB
從數(shù)字來(lái)看,我們的進(jìn)程使用了大概7024M內(nèi)存,距離7637M還有幾百M(fèi)內(nèi)存哪里去了? 哪里去了? 貓吃掉了?
我們?cè)倩仡^來(lái)仔細(xì)看下nmon的內(nèi)存統(tǒng)計(jì)表。
那個(gè)該死的slab是什么呢? 那個(gè)PageTables又是什么呢?
簡(jiǎn)單的說(shuō)內(nèi)核為了高性能每個(gè)需要重復(fù)使用的對(duì)象都會(huì)有個(gè)池,這個(gè)slab池會(huì)cache大量常用的對(duì)象,所以會(huì)消耗大量的內(nèi)存。運(yùn)行命令:
$ slabtop
我們可以看到:
從圖我們可以看出各種對(duì)象的大小和數(shù)目,遺憾的是沒(méi)有告訴我們slab消耗了多少內(nèi)存。
我們自己來(lái)算下好了:
view source
print?
$echo `cat /proc/slabinfo
|awk 'BEGIN{sum=0;}{sum=sum+$3*$4;}END{print
sum/1024/1024}'` MB
904.256
MB
好吧,把每個(gè)對(duì)象的數(shù)目*大小,再累加,我們就得到了總的內(nèi)存消耗量:904M
那么PageTables呢? 我們?nèi)f能的內(nèi)核組的同學(xué)現(xiàn)身了:
伯瑜:
你還沒(méi)有計(jì)算page tables的大小,還有struct page也有一定的大小(每個(gè)頁(yè)一個(gè),64bytes),如果是2.6.32的話,每個(gè)頁(yè)還有一個(gè)page_cgroup(32bytes),也就是說(shuō)內(nèi)存大小的2.3%(96/4096)會(huì)被內(nèi)核固定使用的
含黛:
struct page是系統(tǒng)boot的時(shí)候就會(huì)根據(jù)內(nèi)存大小算出來(lái)分配出去的,18內(nèi)核是1.56%左右,32內(nèi)核由于cgroup的原因會(huì)在2.3%
好吧,知道是干嘛的啦,管理這些物理頁(yè)面的硬開(kāi)銷,那么具體是多少呢?
view source
print?
$echo `grep PageTables
/proc/meminfo |awk '{print $2}'` KB
58052
KB
好吧,小結(jié)下!內(nèi)存的去向主要有3個(gè):1. 進(jìn)程消耗。 2. slab消耗 3.pagetable消耗。
我把三種消耗匯總下和free出的結(jié)果比對(duì)下,這個(gè)腳本的各種計(jì)算項(xiàng)仲同學(xué)幫忙搞定的:
view source
print?
$cat cm.sh
#/bin/bash
for PROCin `ls /proc/|grep "^[0-9]"`
do
if [ -f /proc/$PROC/statm
];then
TEP=`cat /proc/$PROC/statm |awk '{print
($2)}'`
RSS=`expr $RSS + $TEP`
fi
done
RSS=`expr $RSS \* 4`
PageTable=`grep PageTables
/proc/meminfo |awk '{print $2}'`
SlabInfo=`cat /proc/slabinfo
|awk 'BEGIN{sum=0;}{sum=sum+$3*$4;}END{print
sum/1024/1024}'`
echo $RSS"KB", $PageTable"KB", $SlabInfo"MB"
printf "rss+pagetable+slabinfo=%sMB\n" `echo $RSS/1024 + $PageTable/1024 + $SlabInfo|bc`
free -m
$ ./cm.sh
7003756KB, 59272KB, 904.334MB
rss+pagetable+slabinfo=7800.334MB
total?????? usedfree shared
buffers???? cached
Mem:???????? 48262?????? 8050
40211????????? 0???????? 17??????? 404
-/+ buffers/cache:?????? 7629
40633
Swap:???????? 2047??????? 336
1711
free報(bào)告說(shuō)7629M, 我們的cm腳本報(bào)告說(shuō)7800.3M, 我們的CM多報(bào)了171M。
damn,這又怎么回事呢?
我們重新校對(duì)下我們的計(jì)算。 我們和nmon來(lái)比對(duì)下,slab和pagetable的值是吻合的。 那最大的問(wèn)題可能在進(jìn)程的消耗計(jì)算上。
resident resident set size 包括我們使用的各種庫(kù)和so等共享的模塊,在前面的計(jì)算中我們重復(fù)計(jì)算了。
view source
print?
$ pmap `pgrepbash`
...
22923:?? -bash
0000000000400000??? 848K r-x--
/bin/bash
00000000006d3000???? 40K rw---
/bin/bash
00000000006dd000???? 20K rw---??? [
anon ]
00000000008dc000???? 36K rw---
/bin/bash
00000000013c8000??? 592K rw---??? [
anon ]
000000335c400000??? 116K r-x--
/lib64/libtinfo.so.5.7
...
0000003ec5220000????? 4K rw---
/lib64/ld-2.12.so
0000003ec5221000????? 4K rw---??? [
anon ]
0000003ec5800000?? 1628K r-x--
/lib64/libc-2.12.so
...
0000003ec5b9c000???? 20K rw---??? [
anon ]
00007f331b910000? 96836K r----
/usr/lib/locale/locale-archive
00007f33217a1000???? 48K r-x--
/lib64/libnss_files-2.12.so
...
00007f33219af000???? 12K rw---??? [
anon ]
00007f33219bf000????? 8K rw---??? [
anon ]
00007f33219c1000???? 28K r--s-
/usr/lib64/gconv/gconv-modules.cache
00007f33219c8000????? 4K rw---??? [
anon ]
00007fff5e553000???? 84K rw---??? [
stack ]
00007fff5e5e4000????? 4K r-x--??? [
anon ]
ffffffffff600000????? 4K r-x--??? [
anon ]
total
108720K
多出的171M正是共享庫(kù)重復(fù)計(jì)算的部分。
但是由于每個(gè)進(jìn)程共享的東西都不一樣,我們也沒(méi)法知道每個(gè)進(jìn)程是如何共享的,沒(méi)法做到準(zhǔn)確的區(qū)分。
所以只能留點(diǎn)小遺憾,歡迎大家來(lái)探討。
總結(jié):內(nèi)存方面的概念很多,需要深入挖掘!
祝玩的開(kāi)心!
Post Footer automatically generated by wp-posturl plugin for wordpress.
Related posts:
vmtouch-系統(tǒng)pagecache查看和操縱器
Linux下誰(shuí)在消耗我們的cache
BufferedIO和DirectIO混用導(dǎo)致的臟頁(yè)回寫(xiě)問(wèn)題
slabtop簡(jiǎn)單的用途
Linux系統(tǒng)內(nèi)存相關(guān)信息獲取
總結(jié)
以上是生活随笔為你收集整理的linux的used 内存去向,Linux Used内存储器到底哪里去了的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux网络共享文件夹,[Linux]
- 下一篇: linux哪个命令可以切换工作目录?如何