天天看點

釋放buff/cache

總有很多朋友對于Linux的記憶體管理有疑問,之前一篇Linux下的記憶體管理方式似乎也沒能清除大家的疑慮。而在新版核心中,似乎對這個問題提供了新的解決方法,特轉出來給大家參考一下。最後,還附上我對這方法的意見,歡迎各位一同讨論。

當在Linux下頻繁存取檔案後,實體記憶體會很快被用光,當程式結束後,記憶體不會被正常釋放,而是一直作為caching。這個問題,貌似有不少人在問,不過都沒有看到有什麼很好解決的辦法。那麼我來談談這個問題。

一、通常情況

先來說說free指令:

# free -m

total used free shared buffers cached

Mem: 249 163 86 0 10 94

-/+ buffers/Cache: 58 191

SWAP: 511 0 511

其中:

total 記憶體總數

used 已經使用的記憶體數

free 空閑的記憶體數

shared 多個程序共享的記憶體總額

buffers buffer Cache和cached Page Cache 磁盤緩存的大小

-buffers/cache (已用)的記憶體數:used - buffers - cached

+buffers/cache(可用)的記憶體數:free + buffers + cached

可用的memory=free memory+buffers+cached

有了這個基礎後,可以得知,我現在used為163MB,free為86MB,buffer和cached分别為10MB,94MB。

那麼我們來看看,如果我執行複制檔案,記憶體會發生什麼變化。

# cp -r /etc ~/test/

Mem: 249 244 4 0 8 174

-/+ buffers/cache: 62 187

Swap: 511 0 511

在我指令執行結束後,used為244MB,free為4MB,buffers為8MB,cached為174MB,天呐,都被cached吃掉了。别緊張,這是為了提高檔案讀取效率的做法。

為了提高磁盤存取效率,Linux做了一些精心的設計,除了對dentry進行緩存(用于VFS,加速檔案路徑名到inode的轉換),還采取了兩種主要Cache方式:Buffer Cache和Page Cache。前者針對磁盤塊的讀寫,後者針對檔案inode的讀寫。這些Cache有效縮短了 I/O系統調用(比如read,write,getdents)的時間。

那麼有人說過段時間,linux會自動釋放掉所用的記憶體。等待一段時間後,我們使用free再來試試,看看是否有釋放?

Mem: 249 244 5 0 8 174

-/+ buffers/cache: 61 188

似乎沒有任何變化。(實際情況下,記憶體的管理還與Swap有關)那麼我能否手動釋放掉這些記憶體呢?回答是可以的!

二、手動釋放緩存

/proc是一個虛拟檔案系統,我們可以通過對它的讀寫操作做為與Kernel實體間進行通信的一種手段。也就是說可以通過修改/proc中的檔案,來對目前kernel的行為做出調整。那麼我們可以通過調整/proc/sys/vm/drop_caches來釋放記憶體。操作如下:

# cat /proc/sys/vm/drop_caches

首先,/proc/sys/vm/drop_caches的值,預設為0。

# sync

手動執行sync指令(描述:sync 指令運作 sync 子例程。如果必須停止系統,則運作sync 指令以確定檔案系統的完整性。sync 指令将所有未寫的系統緩沖區寫到磁盤中,包含已修改的 i-Node、已延遲的塊 I/O 和讀寫映射檔案)

# echo 1 > /proc/sys/vm/drop_caches   //To free pagecache.

# echo 2 > /proc/sys/vm/drop_caches   //To free dentries and inodes.

# echo 3 > /proc/sys/vm/drop_caches   //To free pagecache,dentries and inodes.

将/proc/sys/vm/drop_caches值設為3

/proc/sys/vm/drop_caches 的值預設為0(是以我們清空後,還再恢複它的值為0)

Mem: 249 66 182 0 0 11

-/+ buffers/cache: 55 194

再來運作free指令,會發現現在的used為66MB,free為182MB,buffers為0MB,cached為11MB。那麼有效的釋放了buffer和cache。

有關/proc/sys/vm/drop_caches的用法在下面進行了說明

/proc/sys/vm/drop_caches (since Linux 2.6.16)

Writing to this file causes the kernel to drop clean caches,dentries and inodes from memory, causing that memory to become free.

To free pagecache, use echo 1 > /proc/sys/vm/drop_caches;

to free dentries and inodes, use echo 2 > /proc/sys/vm/drop_caches;

to free pagecache, dentries and inodes, use echo 3 > /proc/sys/vm/drop_caches.

Because this is a non-destructive operation and dirty objects are not freeable, the user should run sync first.

三、

使用者常見的疑問是,為什麼free這麼小,是否關閉應用後記憶體沒有釋放?但實際上,我們都知道這是因為Linux對記憶體的管理與Windows不同,free小并不是說記憶體不夠用了,應該看的是free的第二行最後一個值:-/+ buffers/cache: 58 191,這才是系統可用的記憶體大小。

實際項目中告訴我們,如果因為是應用有像記憶體洩露、溢出的問題,從swap的使用情況是可以比較快速可以判斷的,但free上面反而比較難檢視。相反,如果在這個時候,我們告訴使用者,修改系統的一個值,“可以”釋放記憶體,free就大了。使用者會怎麼想?不會覺得作業系統“有問題”嗎?是以說,我覺得既然核心是可以快速清空buffer或cache,也不難做到(這從上面的操作中可以明顯看到),但核心并沒有這樣做(預設值是0),我們就不應該随便去改變它。一般情況下,應用在系統上穩定運作了,free值也會保持在一個穩定值的,雖然看上去可能比較小。

當發生記憶體不足、應用擷取不到可用記憶體、OOM錯誤等問題時,還是更應該去分析應用方面的原因,如使用者量太大導緻記憶體不足、發生應用記憶體溢出等情況,否則,清空buffer,強制騰出free的大小,可能隻是把問題給暫時屏蔽了。

繼續閱讀