相信有許多同學都對free命令中的buffers cached十分不理解,今天筆者就對free命令機器結果做一個詳細的剖析。
以下是筆者在虛擬機上運行的debian系統的free情況。該虛擬機內存只有128M,同時分配了256M的SWAP交換區。
total used free shared buffers cached
Mem: 124788 113432 11356 0 15308 75568
-/+ buffers/cache: 22556 102232
Swap: 245752 20 245732
第一行 (可以理解爲從操作系統的角度來看內存分配)
total |
總物理內存大小。 |
used |
已分配的大小,注意,對操作系統來說任何被使用的內存都是used。 |
free |
未被分配的物理內存大小。 |
shared |
共享內存大小,主要用於進程間通信,例如Oracle會使用上GB的共享內存。 |
buffers |
主要用於塊設備數據緩衝,例如記錄文件系統的metadata(目錄、權限等等信息)。 |
cached |
主要用於文件內容緩衝 |
# 這裏補充一下關於文件系統的常識 ^_^
# 文件系統實際上可以粗略的劃分爲兩個部分:
# (1)metadata:即通常說的元數據,包括目錄結構、文件的名字、大小、修改時間、權限等等信息。
# (2)filedata:即文件中真正存儲的內容。
# 由於計算機中各個部件之間的速度相差很大,通常情況下CPU的cache最快,其次是內存,最慢的自然就是硬盤等外部設備了。
# 而越慢的設備越廉價,所以硬盤就被用來存儲大量數據(有一天內存不要錢了大家就不用在被buffer、cache這個東東折磨了 <( ̄︶ ̄)>)。
# 所以,文件系統就被放在了硬盤上(不可避免的悲劇~~)。但是由於硬盤速度實在太慢了,爲了改善IO性能,最終就誕生了"緩存"這一概念。
# "緩存"實際上就是在內存中劃分一塊區域作爲硬盤和進程之間的緩衝區域,寫進程把數據寫到這裏然後就幹其他事情去了,讀進程需要時先在這裏找,找不到再去找硬盤,這樣就大大提高了讀寫效率,同時縮短了IO等待時間,否則你在linux上運行man iptables 這樣的命令的時候每次都會等N久。。。
# 這裏還有一個"物理內存"和"虛擬內存"的概念,這個概念比較難講,大家去google一些大牛的帖子看吧,涉及的東西太多了。。。。
所以,這裏,buffer實際上是用來存儲了文件系統的元數據(這樣我們每次ls就會很快了 ^_^),而cache則緩存了近期讀寫過的文件的內容(第一次讀文件會很慢,以後就會很快,就是因爲有cache的存在),把這個理解了free命令就理解了大半了。
繼續講。。。
第二行 (可以理解爲從應用程序的角度來看內存分配)
-/+ buffers/cached: 22556 102232
這裏的 -/+ 實際上分別指的是 - buffers/cached 和 + buffers/cached 兩個部分。
- buffers/cached |
= used(第一行) - buffers - cached |
實際上是程序當前"真實使用"的"物理內存"的大小。 |
+ buffers/cached |
= buffers + cached |
兩個加起來可以理解爲"暫時借給"系統作爲"緩衝區"使用的內存大小。 |
大家做一下簡單的加減法就清楚了:
從應用多角度來說,實際上系統還可以分配給他的內存有這麼多:11356(free) + 15308(buffers) + 75568(cached)= 102232(free)
而系統所擁有的總的物理內存大小 113432 = 22556( - buffers/cached) + 102232 (+ buffers/cached)
所以,第一行的數據實際上是從操作系統角度來看的。
對於操作系統來說已分配的內存表示已經被某些數據所佔據了,但是具體這些數數據是用來做什麼的他不會去理會。
實際上正如前面所說,這部分物理內存被拿來做"緩存"了。
但是,是不是應用就不能使用了呢?
當然不是!!!!
不然我也不用寫了,大家都懂了。。。
前面說到buffers和cached這部分內存是"借給"操作系統使用的,之所以說是"借的",這裏主要原因還在於"虛擬內存"與"物理內存"的區別。
對於應用來說,我申請了1000KB的內存,操作系統同意了,給程序一個地址,告訴他你要的內存在這裏,然後程序就拿着這個地址去用了。
但是實際上大多數時候程序不會立刻將這些內存使用掉,而是一點一點的使用,所以,在沒有使用之前,系統就能將這一部分物理內存拿去做其他事情已提升整個系統的性能,比如說這裏的"緩存"。
當然,這樣理解"虛擬內存"是非常片面的,實際情況比這要複雜得多,比如說這還涉及到程序的運行空間、代碼的編譯、鏈接、加載等等,必須結合起來才能解釋清楚爲什麼需要虛擬內存,實際上"虛擬內存"是一個抽象的概念的實現,大大簡化了操作系統和應用的設計複雜度。
雖然要講的太多太多,但是,今天這樣理解"虛擬內存"在這裏也夠用了。 ^_^
在這裏操作系統就相當於"借"了一部分內存出去以提高系統的IO性能。
對於"虛擬內存"和"物理內存"可以通過ps aux命令簡單看一下:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1471 0.0 0.3 2152 428 ? S 15:55 0:00 /usr/bin/daemon /etc/init.d/mpt-statusd check_mpt
root 1474 0.0 0.4 1748 556 ? S 15:55 0:00 /bin/sh /etc/init.d/mpt-statusd check_mpt
VSZ這一列顯示的就是對應程序所分配的"虛擬內存"大小,而RSS則是程序實際使用的內存,VSZ實際是比RSS要大的,說明程序沒有使用到他所申請的那麼多內存,如果分配出去了肯定是閒的蛋疼。。。你的機器也不能像現在這樣一邊跑QQ一邊看網頁。。。開個chrome就完蛋了。。
細心的同學會發現,上面講的這個"借"的過程和銀行的業務很相似,大家把手裏的現錢存到銀行去,銀行給我們一張卡,卡上有個卡號,銀行說"憑這個卡和密碼你就可以隨時來取錢了"。然後我們就放心的把錢存在銀行裏,等需要錢的時候就拿着卡去取錢,而銀行這時候也能拿着我們的錢去投資修橋補路。
唯一的區別可能就是銀行有利息,這裏麼有~~~~~
扯遠了,回到主題上。
好,既然我們說這個內存是"借"來的,那當然有程序會拿着地址過來要內存的時候(就跟取錢一樣)。
這時候操作系統就會從第一行的free這裏去找空閒內存分給程序用。
但是大家肯定發現了,大部分的內存是被buffers和cached佔用了,萬一來個需求大的內存的時候怎麼辦?
答案很簡單嘛,把放出去的"貸款"收回來唄~~~~
那就從buffers和cached中釋放內存,同時將所釋放空間中的數據回寫到硬盤上,防止數據丟失。
再插一句,要是buffers和cached也沒了怎麼辦?那"銀行"就只有從其他地方"借錢"來還了~~~
這次"借"就是從硬盤借了,也就是我們所說的分配SWAP空間,將一部分內存頁面換到SWAP空間中。
當然實際的處理過程系統不會等到buffers和cached回收完才使用SWAP空間的,比你想象的要輕易得多,因爲有時候縮小"緩存"的性能代價比使用SWAP空間更高,Linux系統還是很smart的~~~
回來繼續說。
那什麼時候系統會開始回收buffers和cached部分的內存呢?
這裏要看一下數據:
root@debian01:~# cat /proc/meminfo
MemTotal: 124788 kB
MemFree: 11596 kB
Buffers: 15332 kB
Cached: 75568 kB
SwapCached: 20 kB
Active: 54884 kB
Inactive: 45564 kB
Active(anon): 2124 kB
Inactive(anon): 7560 kB
Active(file): 52760 kB
Inactive(file): 38004 kB
Unevictable: 0 kB
Mlocked: 0 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 124788 kB
LowFree: 11596 kB
SwapTotal: 245752 kB
SwapFree: 245732 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 9544 kB
Mapped: 5884 kB
Shmem: 136 kB
Slab: 8784 kB
SReclaimable: 4940 kB
SUnreclaim: 3844 kB
KernelStack: 528 kB
PageTables: 456 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 308144 kB
Committed_AS: 43272 kB
VmallocTotal: 897016 kB
VmallocUsed: 6344 kB
VmallocChunk: 879908 kB
HardwareCorrupted: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 4096 kB
DirectMap4k: 16384 kB
DirectMap4M: 114688 kB
meminfo的數據比較多,這裏就不細講了,我們只關注一個數據。
LowFree: 11596 kB
實際上當free部分的內存小於這個值的時候,系統就會考慮是否需要回收"緩存"部分的物理內存,當然這不是絕對的,這可以作爲一個參考閥值。
OK,最後一部分。
說了這麼多,那麼到底有沒有辦法強制釋放呢??
當然有啊!!!銀行欠你錢你會不去要???
話說辦法其實很簡單,在控制檯執行以下命令即可:
echo 3 > /proc/sys/vm/drop_caches
這裏的"3"表示釋放所有buffers和cached中能釋放的部分。
root@debian01:~# echo 3 > /proc/sys/vm/drop_caches
root@debian01:~# free
total used free shared buffers cached
Mem: 124788 26764 98024 0 148 6144
-/+ buffers/cache: 20472 104316
Swap: 245752 20 245732
手工釋放以後大家可以測試一下,運行幾次類似以下這些命令,會明顯發現又漲上去了。。。
ls -la /dev/
find / -name *.sh
man iptables
root@debian01:~# free
total used free shared buffers cached
Mem: 124788 87368 37420 0 30692 25512
-/+ buffers/cache: 31164 93624
Swap: 245752 20 245732
OK,到這裏free相關的東西就講的差不多了。。。
寫了好久~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~