參考:https://blog.gesha.net/archives/406/
圖中的例子很典型,就是:多數的linux系統在free命令后會發現free(剩余)的內存很少,而自己又沒有開過多的程序或服務。對於上述的情況,正確的解釋是:linux的內存管理機制與windows的有所不同。具體的機制我們無需知道,我們需要知道的是,linux的內存管理機制的思想包括(不敢說就是)內存利用率最大化。內核會把剩余的內存申請為cached,而cached不屬於free范疇。當系統運行時間較久,會發現cached很大,對於有頻繁文件讀寫操作的系統,這種現象會更加明顯。
直觀的看,此時free的內存會非常小,但並不代表可用的內存小,當一個程序需要申請較大的內存時,如果free的內存不夠,內核會把部分cached的內存回收,回收的內存再分配給應用程序。所以對於linux系統,可用於分配的內存不只是free的內存,還包括cached的內存(其實還包括buffers)。
1、通過定期采集/proc文件系統內的meminfo文件來獲取當前內存使用情況:
proc文件系統是一個偽文件系統,它只存在內存當中,而不占用外存空間。它以文件系統的方式為訪問系統內核數據的操作提供接口。用戶和應用程序可以通過proc得到系統的信息,並可以改變內核的某些參數。由於系統的信息,如進程,是動態改變的,所以用戶或應用程序讀取proc文件時,proc文件系統是動態從系統內核讀出所需信息並提交的采集流程圖。/proc/meminfo 信息如下: 需要使用的指標有:MemTotal ,MemFree,Buffers,Cached
MemTotal:總內存大小
MemFree: 空閑內存大小
Buffers和Cached:磁盤緩存的大小Buffers和Cached的區別:buffers 是指用來給塊設備做的緩沖大小,他只記錄文件系統的metadata以及 tracking in-flight pages.
cached 是用來給文件做緩沖。
buffers 是用來存儲目錄里面有什么內容,權限等等。
而cached直接用來記憶我們打開的文件,比如先后執行兩次命令#man X ,你就可以明顯的感覺到第二次的開打的速度快很多。
而buffers隨時都在增加,比如先后兩次使用ls /dev后,就會發現第二次執行的速度會較第一次快。
這就是buffers/chached的區別。
2、下面分別從操作系統角度和應用程序角度來區別Buffers和Cached
使用free命令可以看到

對操作系統來說,Buffers和Cached是已經被使用的(上圖Mem:這一行)
1 MemFree=total-used
2 314952=24946552-24631600
對應用程序來說(上圖對應-/+ buffers/cache那一行)
1 MemFree=buffers+cached+free
2 19536392=152116+19069324+314952
通過看free命令的說明可以發現,free命令的數值是從/proc/meminfo文件重讀取的。查看free的源碼包查看其源碼,明確知道了其中的每個數值的來源(具體內容可查看linux命令free源碼解讀:Procps free.c)。
有時我們計算內存使用率的時候會讀取free命令的回顯,但有時也會直接讀取文件/proc/meminfo的內容,畢竟free命令的回顯數據就是從meminfo文件中獲得的。
然而,由於不同的linux發行版,在系統制作過程中會修改部分源碼。一般的系統(如Debian)使用free命令和讀取meminfo文件兩種方式計算的內存使用率是相同的。但是對於部分系統,如SUSE(並不確定是每個版本的都是,這里指SUSE Enterprise Server 11),其在free命令回顯的結果中,cached部分的值並不等於meminfo文件中的cached所顯示的值,而是等於meminfo文件中cached部分和SReclaimable部分之和。
也就是說,debian之類的系統認為:
可用內存=free的內存+cached的內存+buffers的內存
而SUSE之類的系統則認為:
可用內存=free的內存+cached的內存+buffers的內存+SReclaimable的內存
PS:什么是SReclaimable?在linux內核中會有許多小對象,這些對象構造銷毀十分頻繁,比如i-node,dentry。那么這些對象如果每次構建的時候就向內存要一個頁,而其實際大小可能只有幾個字節,這樣就非常浪費,為了解決這個問題就引入了一種新的機制來處理在同一頁框中如何分配小存儲器區,這個機制可以減少申請和釋放內存帶來的消耗,這些小存儲器區的內存稱為Slab。meminfo文件中標識了Slab的大小,而SReclaimable是指可收回Slab的大小。