首先以Centos6.4的來說,Centos7有些區別
一、buffer/cache/swap的介紹
#cat /etc/redhat-release #查看系統版本
CentOS release 6.4 (Final)
#free -m #查看緩沖區及內存使用情況
total used free shared buffers cached
Mem: 7814 7681 132 0 23 5727
-/+ buffers/cache: 1930 5884
Swap: 8191 32 8159
先看第二行Mem行:
Mem: 7814 7681 132 0 23 5727 #內存總大小為7814MB,使用7681MB,空閑132MB,共享內存0M,buffers:23MB,cached:5727MB
然后看地三行-/+ buffers/cache行:
-/+ buffers/cache: 1930 5884 #(-buffers/cache) used內存數:1930MB(指的第一部分Mem行中的used – buffers – cached),(+buffers/cache) free內存數:5884MB(指的第一部分Mem行中的free + buffers + cached),也就是說-buffers/cache反映的是被程序實實在在吃掉的內存,而+buffers/cache反映的是可以挪用的內存總數.
然后看第四列Swap行:
Swap: 8191 32 8159 #這也就是我們經常說的虛擬內存,8192為swap分區的總大小為8192MB,32為swap分區的使用為32MB,8159為swap空閑為8159MB。
swap分區的作用:
Linux內核為了提高讀寫效率與速度,會將文件在內存中進行緩存,這部分內存就是Cache Memory(緩存內存)。即使你的程序運行結束后,Cache Memory也不會自動釋放。這就會導致你在Linux系統中程序頻繁讀寫文件后,你會發現可用物理內存變少。當系統的物理內存不夠用的時候,就需要將物理內存中的一部分空間釋放出來,以供當前運行的程序使用。那些被釋放的空間可能來自一些很長時間沒有什么操作的程序,這些被釋放的空間被臨時保存到Swap空間中,等到那些程序要運行時,再從Swap分區中恢復保存的數據到內存中。這樣,系統總是在物理內存不夠時,才進行Swap交換。所以swap分區不被占用或者占用很少,說明現在系統內存夠用,運行還算良好,不會影響系統運行。
首先,當物理內存不足以支撐系統和應用程序(進程)的運作時,這個Swap交換分區可以用作臨時存放使用率不高的內存分頁,把騰出的內存交給急需的應用程序(進程)使用。有點類似機房的UPS系統,雖然正常情況下不需要使用,但是異常情況下, Swap交換分區還是會發揮其關鍵作用。
其次,即使你的服務器擁有足夠多的物理內存,也有一些程序會在它們初始化時殘留的極少再用到的內存分頁內容轉移到 swap 空間,以此讓出物理內存空間。對於有發生內存泄漏幾率的應用程序(進程),Swap交換分區更是重要,因為誰也不想看到由於物理內存不足導致系統崩潰。
最后,現在很多個人用戶在使用Linux,有些甚至是PC的虛擬機上跑Linux系統,此時可能常用到休眠(Hibernate),這種情況下也是推薦划分Swap交換分區的。
其實少量使用Swap交換空間是不會影響性能,只有當RAM資源出現瓶頸或者內存泄露,進程異常時導致頻繁、大量使用交換分區才會導致嚴重性能問題。另外使用Swap交換分區頻繁,還會引起kswapd0進程(虛擬內存管理中, 負責換頁的)耗用大量CPU資源,導致CPU飆升。
空閑內存/已用內存換算(也可參考-/+ buffers/cache這行信息也是內存正確使用率):
空閑內存=free(132)+buffers(23)+cached(5727)=5882
已用內存=total(7814)-空閑內存(5882)=1932
buffers和cache的區別:
為了提高磁盤存取效率, Linux做了一些精心的設計, 除了對dentry進行緩存(用於VFS,加速文件路徑名到inode的轉換),還采取了兩種主要Cache方式:Buffer Cache和Page Cache。前者針對磁盤塊的讀寫,后者針對文件inode的讀寫。這些Cache有效縮短了I/O系統調用(比如read,write,getdents)的時間。
磁盤的操作有邏輯級(文件系統)和物理級(磁盤塊),這兩種Cache就是分別緩存邏輯和物理級數據的。
Page cache實際上是針對文件系統的,是文件的緩存,在文件層面上的數據會緩存到page cache。文件的邏輯層需要映射到實際的物理磁盤,這種映射關系由文件系統來完成。當page cache的數據需要刷新時,page cache中的數據交給buffer cache,因為Buffer Cache就是緩存磁盤塊的。但是這種處理在2.6版本的內核之后就變的很簡單了,沒有真正意義上的cache操作。
Buffer cache是針對磁盤塊的緩存,也就是在沒有文件系統的情況下,直接對磁盤進行操作的數據會緩存到buffer cache中,例如,文件系統的元數據都會緩存到buffer cache中。
Buffer:緩沖區,一個用於存儲速度不同步的設備或優先級不同的設備之間傳輸數據的區域。通過緩沖區,可以使進程之間的相互等待變少,從而使從速度慢的設備讀入數據時,速度快的設備的操作進程不發生間斷。
緩沖(buffers)是根據磁盤的讀寫設計的,把分散的寫操作集中進行,減少磁盤碎片和硬盤的反復尋道,從而提高系統性能。linux有一個守護進程定 期清空緩沖內容(即寫如磁盤),也可以通過sync命令手動清空緩沖。
簡單說來,page cache用來緩存文件數據,buffer cache用來緩存磁盤數據。在有文件系統的情況下,對文件操作,那么數據會緩存到page cache,如果直接采用dd等工具對磁盤進行讀寫,那么數據會緩存到buffer cache。
所以我們看linux,只要不用swap的交換空間,就不用擔心自己的內存太少.如果常常swap用很多,可能你就要考慮加物理內存了.這也是linux看內存是否夠用的標准.
如果 cache 的值很大,說明cache住的文件數很多。如果頻繁訪問到的文件都能被cache住,那么磁盤的讀IO bi會非常小。
注:下面是Centos7.2系統free -m的顯示:
#free -m
total used free shared buff/cache available
Mem: 64252 2924 258 3233 61069 57654
Swap: 8191 144 8047
博文來自:www.51niux.com
二、內存查看命令
2.1 用free加各種參數例如:
命令參數:
-b 以Byte為單位顯示內存使用情況。
-k 以KB為單位顯示內存使用情況。
-m 以MB為單位顯示內存使用情況。
-g 以GB為單位顯示內存使用情況。
-o 不顯示緩沖區調節列。
-s<間隔秒數> 持續觀察內存使用狀況。
-t 顯示內存總和列。
-V 顯示版本信息。
# free -k -s 1 #顯示單位為KB,然后每一秒刷新一次。
但是這也只能顯示一個總量,如果內存真的是被使用了,我們應該如何查詢哪些進程占用內存過大呢?
2.2 top命令
執行top,然后按shift+M,可以對進行使用內存情況從大到小排序
2.3 ps命令
# ps -aux|sort -k 4 -n #為了查看方便,讓其從小到大排序
第一列:USER 用戶名
第二列:PID 進程ID
第三列:%CPU 進程的cpu占用率
第四列:%MEM 進程的內存占用率
第五列:VSZ 虛擬內存中進程的大小,單位KB
第六列:RSS 進程實際內存大小,單位KB
第七列:TTY 與進程關聯的終端(tty)
第八列:STAT 進程的狀態
下面為STAT的狀態碼:
R 運行 Runnable (on run queue) 正在運行或在運行隊列中等待。
S 睡眠 Sleeping 休眠中, 受阻, 在等待某個條件的形成或接受到信號。
I 空閑 Idle
Z 僵死 Zombie(a defunct process) 進程已終止, 但進程描述符存在, 直到父進程調用wait4()系統調用后釋放。
D 不可中斷 Uninterruptible sleep (ususally IO) 收到信號不喚醒和不可運行, 進程必須等待直到有中斷發生。
T 終止 Terminate 進程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信號后停止運行運行。
P 等待交換頁
W 無駐留頁 has no resident pages 沒有足夠的記憶體分頁可分配。
X 死掉的進程
< 高優先級進程 高優先序的進程
N 低優先 級進程 低優先序的進程
L 內存鎖頁 Lock 有記憶體分頁分配並縮在記憶體內
s 進程的領導者(在它之下有子進程);
l 多進程的(使用 CLONE_THREAD, 類似 NPTL pthreads)
+ 位於后台的進程組
第九列:START 進程啟動時間和日期
第十列:TIME 進程使用的總cpu時間
第十一列: COMMAND 正在執行的命令行命令
注:如果要進一步排查內存占用問題,可以用# pstree PID -ap #樹狀圖的顯示進程間的關系,默認PID為1,也就是全部
# ps -eo user,pid,command|grep mysql #查出mysql的uid
# pstree 3584 -ap #查看mysql下面都有哪些進程
注:pgrep
pgrep命令以名稱為依據從運行進程隊列中查找進程,並顯示查找到的進程id。每一個進程ID以一個十進制數表示,通過一個分割字符串和下一個ID分開,默認的分割字符串是一個新行。對於每個屬性選項,用戶可以在命令行上指定一個以逗號分割的可能值的集合
參數: -o:僅顯示找到的最小(起始)進程號; -n:僅顯示找到的最大(結束)進程號; -l:顯示進程名稱; -P:指定父進程號; -g:指定進程組; -t:指定開啟進程的終端; -u:指定進程的有效用戶ID。
# pgrep -l mysqld
3584 mysqld_safe
3752 mysqld
博文來自:www.51niux.com
2.4 #cat /proc/meminfo #又或者說,我發現系統占用內存不大,內存都被緩存起來了,想看看內存使用的詳細信息。
#cat /proc/meminfo
MemTotal: 8002048 kB #所有可用RAM大小(即物理內存減去一些預留位和內核的二進制代碼大小)
MemFree: 141316 kB #LowFree和HighFree的綜合,被系統留着未使用的內存
Buffers: 3492 kB #用來給文件做緩沖大小
Cached: 5850688 kB #被高速緩沖存儲器(cache memory)用的內存的大小
SwapCached: 1004 kB #被高速緩沖存儲器(cache memory)用的交換空間的大小
Active: 3685356 kB #在活躍使用中的緩沖或高速緩沖存儲器頁面文件的大小,除非非常必要否則不會被移作他用.
Inactive: 3634468 kB # 在不經常使用中的緩沖或高速緩沖存儲器頁面文件的大小,可能被用於其他途徑.
Active(anon): 760408 kB
Inactive(anon): 706016 kB
Active(file): 2924948 kB
Inactive(file): 2928452 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 8388600 kB #交換空間的總大小
SwapFree: 8355464 kB #未被使用交換空間的大小
Dirty: 60612 kB #等待被寫回到磁盤的內存大小
Writeback: 44 kB #正在被寫回到磁盤的內存大小
AnonPages: 1465384 kB #未映射頁的內存大小
Mapped: 10028 kB #設備和文件等映射的大小
Shmem: 128 kB
Slab: 393984 kB #內核數據結構緩存的大小,可以減少申請和釋放內存帶來的消耗。
SReclaimable: 314272 kB #可收回Slab的大小
SUnreclaim: 79712 kB #不可收回Slab的大小(SUnreclaim+SReclaimable=Slab)
KernelStack: 6656 kB
PageTables: 13848 kB #管理內存分頁頁面的索引表的大小。
NFS_Unstable: 0 kB #不穩定頁表的大小
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 12389624 kB
Committed_AS: 6404932 kB
VmallocTotal: 34359738367 kB #可以vmalloc虛擬內存大小
VmallocUsed: 291660 kB #已經被使用的虛擬內存大小
VmallocChunk: 34359426484 kB
HardwareCorrupted: 0 kB
AnonHugePages: 243712 kB
HugePages_Total: 0 #內存大頁的總數
HugePages_Free: 0 #內存大頁剩余數量
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB #內存大頁的大小(64位操作系統中有2MB/1GB兩種,默認是2MB。)
DirectMap4k: 4096 kB
DirectMap2M: 2084864 kB
DirectMap1G: 6291456 kB
博文來自:www.51niux.com
三、手工釋放內存區緩存(這是只是記錄,但是不建議操作,本來cache就是為了提升系統性能,是linux區別於windows的優勢所在,緩解磁盤的壓力,如果真有必要可手工釋放一下,也不要永久的的讓cache作用無法發揮)
# sync; echo 1 > /proc/sys/vm/drop_caches #釋放 pagecache
# sync; echo 2 > /proc/sys/vm/drop_caches #釋放 dentries 和 inodes:
# sync; echo 3 > /proc/sys/vm/drop_caches #釋放 pagecache,dentries 和 inodes:
# sync; echo 0 > /proc/sys/vm/drop_caches #默認0為不釋放,讓系統自己調節
注:
操作前要使用sync,強制將內存中內容寫入硬盤,包含已修改的 i-node、已延遲的塊 I/O 和讀寫映射文件。這一步是確保第二步的安全性。防止數據或操作丟失。
linux內核2.6和內核3系列的區別:
內核2.6的版本執行上述的操作都沒問題的,但是到了內核3系列,就不能執行echo 0 >/proc/sys/vm/drop_caches的操作了,這是一個坑,重啟才能改回去
# echo 0 >/proc/sys/vm/drop_caches
-bash: echo: write error: Invalid argument
# sysctl -a|grep vm.drop_caches #內核中有這個參數
vm.drop_caches = 3
# sysctl -w vm.drop_caches=0 #也寫不進去,這個在內核2.6系列上面可以的,這也是手工釋放內存緩存的另一種形式(sysctl -w vm.drop_caches=3)
error: "Invalid argument" setting key "vm.drop_caches"
# sysctl -w vm.drop_caches=1 #執行其他的是沒問題的,但是就是執行0的插入不可以,要重啟服務器。
vm.drop_caches = 1
注:
swap清理:
swapoff -a && swapon -a
注意:這樣清理有個前提條件,空閑的內存必須比已經使用的swap空間大。
上述只是暫時生效,但是系統重啟后,系統還是按照自己默認的方法去使用緩存,有的網友會寫定時任務腳本晚上去釋放一下內存cache,還有一種暴力的永久生效的方法,使cache的作用基本無法發揮。
修改/etc/sysctl.conf 添加如下選項后就不會內存持續增加(這些配置摘抄自網上,未做測試,只是記錄一下)
vm.dirty_ratio = 1
vm.dirty_background_ratio=1
vm.dirty_writeback_centisecs=2
vm.dirty_expire_centisecs=3
vm.drop_caches=3
vm.swappiness =100
vm.vfs_cache_pressure=163
vm.overcommit_memory=2
vm.lowmem_reserve_ratio=32 32 8
kern.maxvnodes=3
#下面是相關解釋:
/proc/sys/vm/dirty_ratio
這個參數控制文件系統的文件系統寫緩沖區的大小,單位是百分比,表示系統內存的百分比,表示當寫緩沖使用到系統內存多少的時候,開始向磁盤寫出數據。增大之會使用更多系統內存用於磁盤寫緩沖,也可以極大提高系統的寫性能。但是,當你需要持續、恆定的寫入場合時,應該降低其數值,一般啟動上缺省是 10。設1加速程序速度
/proc/sys/vm/dirty_background_ratio
這個參數控制文件系統的pdflush進程,在何時刷新磁盤。單位是百分比,表示系統內存的百分比,意思是當寫緩沖使用到系統內存多少的時候,pdflush開始向磁盤寫出數據。增大之會使用更多系統內存用於磁盤寫緩沖,也可以極大提高系統的寫性能。但是,當你需要持續、恆定的寫入場合時,應該降低其數值,一般啟動上缺省是 5
/proc/sys/vm/dirty_writeback_centisecs
這個參數控制內核的臟數據刷新進程pdflush的運行間隔。單位是 1/100 秒。缺省數值是500,也就是 5 秒。如果你的系統是持續地寫入動作,那么實際上還是降低這個數值比較好,這樣可以把尖峰的寫操作削平成多次寫操
/proc/sys/vm/dirty_expire_centisecs
這個參數聲明Linux內核寫緩沖區里面的數據多“舊”了之后,pdflush進程就開始考慮寫到磁盤中去。單位是 1/100秒。缺省是 30000,也就是 30 秒的數據就算舊了,將會刷新磁盤。對於特別重載的寫操作來說,這個值適當縮小也是好的,但也不能縮小太多,因為縮小太多也會導致IO提高太快。建議設置為 1500,也就是15秒算舊。
/proc/sys/vm/drop_caches
釋放已經使用的cache
/proc/sys/vm/page-cluster
該文件表示在寫一次到swap區的時候寫入的頁面數量,0表示1頁,1表示2頁,2表示4頁。
/proc/sys/vm/swapiness
該文件表示系統進行交換行為的程度,數值(0-100)越高,越可能發生磁盤交換。
/proc/sys/vm/vfs_cache_pressure
該文件表示內核回收用於directory和inode cache內存的傾向