--Linux內存詳解
-----------------2014/05/24
Linux的內存上表現的不像windows那么直觀,本文准備詳細的介紹一下Linux的內存。
請看這下有linux命令free和vmstat輸出的內存信息。
Mem行used表示已經分配的內存,free表示尚未分配的內存,shared表示共享內存。
計算方法:緩存統計行free=Mem(free)+Mem(buffers)+Mem(cached)
共享內存
對於共享內存(Shared memory),主要用於在UNIX 環境下不同進程之間共享數據,是進程間通信的一種方法,一般的應用程序不會申請使用共享內存,筆者也沒有去驗證共享內存對上面等式的影響。
例如Linux平台的oracle為多進程程序,SGA和PGA都是各進程共享和通信的數據區域,所有可以看到分配了很大的共享內存。而MySQL為多線程,系統級表現為一個進程,不需要共享內存。
Linux的cache和buffer有何區別
Linux下對文件的訪問和設備的訪問通常會被cache起來加快訪問速度,這個是系統的默認行為。 而cache需要耗費我們的內存,雖然這個內存最后可以通過echo 3>/proc/sys/vm/drop_caches這樣的命令來主動釋放。但是有時候我們還是需要理解誰消耗了我們的內存。
我們來先了解下內存的使用情況:
[root@my031045 ~]# free
total used free shared buffers cached
Mem: 24676836 626568 24050268 0 30884 508312
-/+ buffers/cache: 87372 24589464
Swap: 8385760
Page cache和buffer cache一直以來是兩個比較容易混淆的概念,在網上也有很多人在爭辯和猜想這兩個cache到底有什么區別,討論到最后也一直沒有一個統一和正
確的結論,在我工作的這一段時間,page cache和buffer cache的概念曾經困擾過我,但是仔細分析一下,這兩個概念實際上非常的清晰。如果能夠了解到這兩個cache的本質,那么我們在分析io問題的時候可能會更加得心應手。 Page cache實際上是針對文件系統的,是文件的緩存,在文件層面上的數據會緩存到page cache。文件的邏輯層需要映射到實際的物理磁盤,這種映射關系由文件系統來完成。當page cache的數據需要刷新時,page cache中的數據交給buffer cache,但是這種處理在2.6版本的內核之后就變的很簡單了,沒有真正意義上的cache操作。
Buffer cache是針對磁盤塊的緩存,也就是在沒有文件系統的情況下,直接對磁盤進行操作的數據會緩存到buffer cache中,例如,文件系統的元數據都會緩存到buffer cache中。
簡單說來,page cache用來緩存文件數據,buffer cache用來緩存磁盤數據。在有文件系統的情況下,對文件操作,那么數據會緩存到page cache,如果直接采用
dd等工具對磁盤進行讀寫,那么數據會緩存到buffer cache補充一點,在文件系統層每個設備都會分配一個def_blk_ops的文件操作方法,這是設備的操作方法,在每個設備的inode下面會存在一個radix tree,這個radix tree下面將會放置緩存數據的page頁。這個page的數量將會在top程序的buffer一欄中顯示。如果設備做了文件系統,那么會生成一個inode,這個inode會分配ext3_ops之類的操作方法,這些方法是文件系統的方法,在這個inode下面同樣存在一個radix tree,這里會緩存文件的page頁,緩存頁的數量在top程序的cache一欄進行統計。從上面的分析可以看出,2.6內核中的buffer cache和page cache在處理上是保持一致的,但是存在概念上的差別,page cache針對文件的cache,buffer是針對磁盤塊數據的cache,僅此而已。
有了偉大的systemtap, 我們可以用stap腳本來了解誰在消耗我們的cache了:
#這個命令行用來調查誰在加數據入page_cache
[root@my031045 ~]# stap -e 'probe vfs.add_to_page_cache {printf("dev=%d, devname=%s, ino=%d, index=%d, nrpages=%d/n", dev, devname, ino, index, nrpages )}'
...
dev=2, devname=N/A, ino=0, index=2975, nrpages=1777
dev=2, devname=N/A, ino=0, index=3399, nrpages=2594
dev=2, devname=N/A, ino=0, index=3034, nrpages=1778
dev=2, devname=N/A, ino=0, index=3618, nrpages=2595
dev=2, devname=N/A, ino=0, index=1694, nrpages=106
dev=2, devname=N/A, ino=0, index=1703, nrpages=107
dev=2, devname=N/A, ino=0, index=1810, nrpages=210
dev=2, devname=N/A, ino=0, index=1812, nrpages=211
...
這時候我們拷貝個大文件:
[chuba@my031045 ~]$ cp huge_foo.file bar
#這時候我們可以看到文件的內容被猛的添加到cache去:
...
dev=8388614, devname=sda6, ino=2399271, index=39393, nrpages=39393
dev=8388614, devname=sda6, ino=2399271, index=39394, nrpages=39394
dev=8388614, devname=sda6, ino=2399271, index=39395, nrpages=39395
dev=8388614, devname=sda6, ino=2399271, index=39396, nrpages=39396
dev=8388614, devname=sda6, ino=2399271, index=39397, nrpages=39397
dev=8388614, devname=sda6, ino=2399271, index=39398, nrpages=39398
dev=8388614, devname=sda6, ino=2399271, index=39399, nrpages=39399
dev=8388614, devname=sda6, ino=2399271, index=39400, nrpages=39400
dev=8388614, devname=sda6, ino=2399271, index=39401, nrpages=39401
dev=8388614, devname=sda6, ino=2399271, index=39402, nrpages=39402
dev=8388614, devname=sda6, ino=2399271, index=39403, nrpages=39403
dev=8388614, devname=sda6, ino=2399271, index=39404, nrpages=39404
dev=8388614, devname=sda6, ino=2399271, index=39405, nrpages=39405
dev=8388614, devname=sda6, ino=2399271, index=39406, nrpages=39406
dev=8388614, devname=sda6, ino=2399271, index=39407, nrpages=39407
dev=8388614, devname=sda6, ino=2399271, index=39408, nrpages=39408
dev=8388614, devname=sda6, ino=2399271, index=39409, nrpages=39409
dev=8388614, devname=sda6, ino=2399271, index=39410, nrpages=39410
dev=8388614, devname=sda6, ino=2399271, index=39411, nrpages=39411
...
如果需要手動釋放Linux系統的Cache,可以參考博文:http://www.cnblogs.com/jackhub/p/3736877.html