一、概述
在日常運維中,我們會發現主機內存使用告警,為什么Linux系統沒運行多少程序,顯示的可用內存這么少?其實Linux與Win的內存管理不同,會盡量緩存內存以提高讀寫性能,通常叫做Cache Memory。
有時候你會發現沒有什么程序在運行,但是使用top或free命令看到可用內存free顯示很少,我們可以使用cat /proc/meminfo 或free -m查看內存信息,還有一項 Cached Memory:
[root@localhost ~]# free -m total used free shared buff/cache available Mem: 7815 1410 4959 32 1445 4101 Swap: 2047 0 2047 [root@localhost ~]# cat /proc/meminfo MemTotal: 8003408 kB MemFree: 5080476 kB MemAvailable: 4201416 kB Buffers: 1068 kB Cached: 1386772 kB SwapCached: 0 kB Active: 2234760 kB Inactive: 422508 kB Active(anon): 1285588 kB Inactive(anon): 17228 kB Active(file): 949172 kB Inactive(file): 405280 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 2097148 kB SwapFree: 2097148 kB Dirty: 8 kB Writeback: 0 kB AnonPages: 1269464 kB Mapped: 48816 kB Shmem: 33388 kB Slab: 127600 kB SReclaimable: 92416 kB SUnreclaim: 35184 kB KernelStack: 3456 kB PageTables: 7600 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 6098852 kB Committed_AS: 1486200 kB VmallocTotal: 34359738367 kB VmallocUsed: 25856 kB VmallocChunk: 34359710204 kB HardwareCorrupted: 0 kB AnonHugePages: 1118208 kB CmaTotal: 0 kB CmaFree: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 83968 kB DirectMap2M: 5154816 kB DirectMap1G: 3145728 kB
1、基本概念
第一列Mem
內存的使用信息Swap
交換空間的使用信息
第一行total
系統總的可用物理內存大小used
已被使用的物理內存大小free
還有多少物理內存可用shared
被共享使用的物理內存大小buff/cache
被 buffer 和 cache 使用的物理內存大小available
還可以被應用程序使用的物理內存大小
free 與 available 的區別
free 是真正尚未被使用的物理內存數量。
available 是應用程序認為可用內存數量,available = free + buffer + cache (注:只是大概的計算方法)
2、緩存機制介紹
在Linux系統中,為了提高文件系統性能,內核利用一部分物理內存分配出緩沖區,用於緩存系統操作和數據文件,當內核收到讀寫的請求時,內核先去緩存區找是否有請求的數據,有就直接返回,如果沒有則通過驅動程序直接操作磁盤。對於內核來說,buffer 和 cache 其實都屬於已經被使用的內存。但當應用程序申請內存時,如果 free 內存不夠,內核就會回收 buffer 和 cache 的內存來滿足應用程序的請求。這就是稍后要說明的 buffer 和 cache。
緩存機制優點:減少系統調用次數,降低CPU上下文切換和磁盤訪問頻率。
CPU上下文切換:CPU給每個進程一定的服務時間,當時間片用完后,內核從正在運行的進程中收回處理器,同時把進程當前運行狀態保存下來,然后加載下一個任務,這個過程叫做上下文切換。實質上就是被終止運行進程與待運行進程的進程切換。
二、緩存區分buffers和cached區別
內核在保證系統能正常使用物理內存和數據量讀寫情況下來分配緩沖區大小。
buffers用來緩存metadata及pages,可以理解為系統緩存,例如,vi打開一個文件。
cached是用來給文件做緩存,可以理解為數據塊緩存,例如,dd if=/dev/zero of=/tmp/test count=1 bs=1G 測試寫入一個文件,就會被緩存到緩沖區中,當下一次再執行這個測試命令時,寫入速度會明顯很快。
具體解釋:
buffer和cache是兩個在計算機技術中被用濫的名詞,放在不通語境下會有不同的意義。在Linux的內存管理中,這里的buffer指Linux內存的:Buffer cache。這里的cache指Linux內存中的:Page cache。翻譯成中文可以叫做緩沖區緩存和頁面緩存。在歷史上,它們一個(buffer)被用來當成對io設備寫的緩存,而另一個(cache)被用來當作對io設備的讀緩存,這里的io設備,主要指的是塊設備文件和文件系統上的普通文件。但是現在,它們的意義已經不一樣了。在當前的內核中,page cache顧名思義就是針對內存頁的緩存,說白了就是,如果有內存是以page進行分配管理的,都可以使用page cache作為其緩存來管理使用。當然,不是所有的內存都是以頁(page)進行管理的,也有很多是針對塊(block)進行管理的,這部分內存使用如果要用到cache功能,則都集中到buffer cache中來使用。(從這個角度出發,是不是buffer cache改名叫做block cache更好?)然而,也不是所有塊(block)都有固定長度,系統上塊的長度主要是根據所使用的塊設備決定的,而頁長度在X86上無論是32位還是64位都是4k。
1、什么是page cache?
Page cache主要用來作為文件系統上的文件數據的緩存來用,尤其是針對當進程對文件有read/write操作的時候。如果你仔細想想的話,作為可以映射文件到內存的系統調用:mmap是不是很自然的也應該用到page cache?在當前的系統實現里,page cache也被作為其它文件類型的緩存設備來用,所以事實上page cache也負責了大部分的塊設備文件的緩存工作。
2、什么是buffer cache?
Buffer cache則主要是設計用來在系統對塊設備進行讀寫的時候,對塊進行數據緩存的系統來使用。這意味着某些對塊的操作會使用buffer cache進行緩存,比如我們在格式化文件系統的時候。一般情況下兩個緩存系統是一起配合使用的,比如當我們對一個文件進行寫操作的時候,page cache的內容會被改變,而buffer cache則可以用來將page標記為不同的緩沖區,並記錄是哪一個緩沖區被修改了。這樣,內核在后續執行臟數據的回寫(writeback)時,就不用將整個page寫回,而只需要寫回修改的部分即可。
三、Swap用途
Swap意思是交換分區,通常我們說的虛擬內存,是從硬盤中划分出的一個分區。當物理內存不夠用的時候,內核就會釋放緩存區(buffers/cache)里一些長時間不用的程序,然后將這些程序臨時放到Swap中,也就是說如果物理內存和緩存區內存不夠用的時候,才會用到Swap。
swap清理:
swapoff -a && swapon -a
注意:這樣清理有個前提條件,空閑的內存必須比已經使用的swap空間大
四、釋放緩存區內存的方法
1、清理pagecache(頁面緩存) [root@localhost ~]#echo 1 > /proc/sys/vm/drop_caches 或者 [root@localhost ~]# sysctl -w vm.drop_caches=1 2、清理dentries(目錄緩存)和inodes [root@localhost ~]# echo 2 > /proc/sys/vm/drop_caches 或者 [root@localhost ~]# sysctl -w vm.drop_caches=2 3、清理pagecache、dentries和inodes [root@localhost ~]# echo 3 > /proc/sys/vm/drop_caches 或者 [root@localhost ~]# sysctl -w vm.drop_caches=3
這個文件可以設置的值分別為1、2、3。它們所表示的含義為:
echo 1 > /proc/sys/vm/drop_caches:表示清除pagecache。 echo 2 > /proc/sys/vm/drop_caches:表示清除回收slab分配器中的對象(包括目錄項緩存和inode緩存)。slab分配器是內核中管理內存的一種機制,其中很多緩存數據實現都是用的pagecache。 echo 3 > /proc/sys/vm/drop_caches:表示清除pagecache和slab分配器中的緩存對象。
上面三種方式都是臨時釋放緩存的方法,要想永久釋放緩存,需要在/etc/sysctl.conf文件中配置:vm.drop_caches=1/2/3,然后sysctl -p生效即可!
另外,可以使用sync命令來清理文件系統緩存,還會清理僵屍(zombie)對象和它們占用的內存
[root@localhost ~]# sync
五、注意事項
關於清除緩存的操作在大多數情況下都不會對系統造成傷害,只會有助於釋放不用的內存。
但是如果在執行這些操作時正在寫數據,那么實際上在數據到達磁盤之前就將它從文件緩存中清除掉了,這可能會造成很不好的影響。那么如果避免這種事情發生呢?
因此,這里不得不提一下/proc/sys/vm/vfs_cache_pressure這個文件,告訴內核,當清理inoe/dentry緩存時應該用什么樣的優先級。
vfs_cache_pressure=100 這個是默認值,內核會嘗試重新聲明dentries和inodes,並采用一種相對於頁面緩存和交換緩存比較”合理”的比例。 減少vfs_cache_pressure的值,會導致內核傾向於保留dentry和inode緩存。 增加vfs_cache_pressure的值,(即超過100時),則會導致內核傾向於重新聲明dentries和inodes 總之,vfs_cache_pressure的值: 小於100的值不會導致緩存的大量減少 超過100的值則會告訴內核你希望以高優先級來清理緩存。 其實無論vfs_cache_pressure的值采用什么值,內核清理緩存的速度都是比較低的。 如果將此值設置為10000,系統將會將緩存減少到一個合理的水平。
釋放內存前先使用sync命令做同步,以確保文件系統的完整性,將所有未寫的系統緩沖區寫到磁盤中,包含已修改的 i-node、已延遲的塊 I/O 和讀寫映射文件。否則在釋放緩存的過程中,可能會丟失未保存的文件。
/proc是一個虛擬文件系統,可以通過對它的讀寫操作作為與kernel實體間進行通信的一種手段。也就是說可以通過修改/proc中的文件,來對當前kernel的行為做出調整。也就是說我們可以通過調整/proc/sys/vm/drop_caches來釋放內存。
drop_caches的值可以是0-3之間的數字,代表不同的含義:
0:不釋放(系統默認值)
1:釋放頁緩存
2:釋放dentries和inodes
3:釋放所有緩存
-----------------------------------------------------------書山有路勤為徑,學海無涯苦作舟-------------------------------------------------------------