Linux 的記憶體快取(Cache Memory)功能 - Linux 系統把記憶體用光了?

這裡 Linux 記憶體中的記憶體快取(Cache Memory)是什麼,並討論相關的一些指令用法。

在 Linux 中系統會將暫時沒有用到的記憶體借來當作磁碟的快取(cache),而在用 top 指令看系統的 free 的記憶體時,感覺記憶體好像所剩無幾,有些人就會以為 Linux 系統把記憶體吃光光了,然後就推測這樣系統會用到 swap 記憶體,效能也會跟著下降,但其實不是這樣的,而且真正的情況剛好相反。

實際上 Linux 系統拿沒有用到的記憶體當作硬碟的快取,可以會讓整個系統的效能提昇很多,而且沒有任何副作用(除了讓一些不了解的人很緊張之外),它只是「暫時」把沒有用到的記憶體借來用一下而已,當有程式需要記憶體時,系統就會馬上把記憶體拿回來給需要記憶體的程式使用,完全沒有霸佔記憶體的問題。

有些人也會擔心這樣的機制會不會讓系統使用到 swap 記憶體?事實上這也不用擔心,快取只會用到暫時沒有使用 RAM,並不會使用到 swap 來作為快取(使用 swap 也沒什麼意義,因為 swap 就是在磁碟上,不會比較快)。

至於有時候整個系統中沒有在執行什麼程式,而用 topfree 指令查看記憶體使用狀況時,會顯示很大一部分的記憶體是 used 的狀態,不懂的人就會感覺很奇怪,這其實是對於他的意義有些誤解,我們用下面這個表來解釋:
記憶體狀態你的認知Linux 系統的認知
正在被應用程式使用UsedUsed
可以被應用程式使用,但被暫時借去做別的用途FreeUsed
沒有被使用FreeFree
會出問題就在於記憶體暫時借去做別的用途時(像硬碟快取),Linux 系統會顯示 used,但是大部分人應該會認為這部份的記憶體應該顯示為 free,就是因為這個落差,導致很多人誤以為系統的記憶體被吃光,換句話說,那些被標示為 used 的記憶體其實包含被拿去作為快取的部份,而這些部份其實在程式需要時是可以馬上拿回來的,所以可以被一般應用程式使用的記憶體會比你想像的要多一些。

既然看一般的 top 輸出的 free 記憶體不太準,那到底要如何知道我們實際上真正可以用的記憶體有多少呢?其實可以使用 free 指令來看,只是在看他的輸出的時候,要知道看哪一個欄位:
free -m
輸出為:
             total       used       free     shared    buffers     cached
Mem:          3953       3154        799          0        135        990
-/+ buffers/cache:       2029       1924
Swap:         3813          0       3813
若要看實際上應用程式可用的記憶體就看 -/+ buffers/cache 這一行的 free 這一欄有多少就是了,我們這裡使用 -m 參數,所以這裡的單位都是 MB,以這個例子來說就是還有 1924 MB 可以使用,而如果你只是單純看上面的 Mem 那一行,你可能會以為系統只剩下 799 MB 的記憶體了。

除了使用 free 指令之外,也可以使用比較直覺的 htop 工具,它類似 top 指令,但是有更人性化的輸出,下面這個是他的使用畫面:

htop 畫面

其中 Mem 的部份就會顯示目前的記憶體使用狀況,而它會以不同顏色表示不同的記憶體的使用狀況,像快取的話就會使用黃色表示,這樣可以讓管理者更容易看出整體記憶體的狀況。

網路上有很多清除快取記憶體的教學,這些動作其實對於整個系統效能是沒有幫助的,甚至你把硬碟快取強制清除之後,因為沒有快取的輔助,導致有些資料還要重新從硬碟讀取,反而讓整體效能更差也不一定,而且重點是不管你有沒有去手動釋放快取記憶體,只要你的程式需要記憶體時,都可以馬上使用這些記憶體空間,所以跟本不需要多花這些力氣。

以下是手動清除快取記憶體的方式,這裡只是純粹的討論技術,這個部份通常一般人是沒有什麼機會需要用到的,除非你有一些很特殊的需求,而且在做這些動作之前,你應該要很清楚自己在做什麼與需要什麼。

要釋放 Linux 的記憶體快取,可以透過更改 /proc/sys/vm/drop_caches 這個檔案的內容來達到,當這個檔案內容被設為 1 時,是表示要求 Linux 釋放沒在使用的一般性快取(pagecache),而設為 2 時,則代表要求釋放 dentry 與 inode 所使用到的快取,若設為 3 則是釋放所有的快取(也就是包含 1 與 2 的狀況)。

在設定時,也可以加上 sync 指令,讓一些沒有寫入硬碟的資料先寫入之後,才將快取釋放,另外這個指令會需要 root 權限,所以整個完整的指令就會像這樣:
sudo sh -c "sync; echo 3 > /proc/sys/vm/drop_caches"
另外,如果不想使用 echo,也可以用 sysctl 指令的方式:
sudo sysctl vm.drop_caches=3
最後再強調一次,這個釋放快取的動作在大部分的狀況是沒有什麼好處的,所以如果你要使用,請先搞清楚這是在做什麼。
本站已經搬家了,欲查看最新的文章,請至 G. T. Wang 新網站