查看Linux內存使用率
1、 一般情況下大家查看系統內存使用情況都會用到free -m或free –g 命令來查看(如圖)

但是多數情況大家對如何得出准確的內存使用率有些迷惑,因為多數的linux系統在free命令后會發現free(剩余)的內存很少,而自己又沒有開過多的程序或服務。對於上述的情況,正確的解釋是:linux的內存管理機制與windows的有所不同。具體的機制我們無需知道,我們需要知道的是,linux的內存管理機制的思想包括(不敢說就是)內存利用率最大化。內核會把剩余的內存申請為cached,而cached不屬於free范疇。當系統運行時間較久,會發現cached很大,對於有頻繁文件讀寫操作的系統,這種現象會更加明顯。
直觀的看,此時free的內存會非常小,但並不代表可用的內存小,當一個程序需要申請較大的內存時,如果free的內存不夠,內核會把部分cached的內存回收,回收的內存再分配給應用程序。所以對於linux系統,可用於分配的內存不只是free的內存,還包括cached的內存(其實還包括buffers)。
對操作系統來說,Buffers和Cached是已經被使用的(上圖Mem:這一行)
1 MemFree=total-used
2 2G=62G-60G
對應用程序來說(上圖)
1 MemFree=buffers+cached+free
2 41G=2G+0G+39G
由於不同的linux發行版,在系統制作過程中會修改部分源碼。一般的系統(如Debian)使用free命令和讀取meminfo文件兩種方式計算的內存使用率是相同的。但是對於部分系統,如SUSE(並不確定是每個版本的都是,這里指SUSE Enterprise Server 11),其在free命令回顯的結果中,cached部分的值並不等於meminfo文件中的cached所顯示的值,而是等於meminfo文件中cached部分和SReclaimable部分之和。
也就是說,debian之類的系統為:
可用內存=free的內存+cached的內存+buffers的內存 (上圖Mem:這一行)
而SUSE之類的系統則為:
可用內存=free的內存+cached的內存+buffers的內存+SReclaimable的內存
Linux服務器內存監控攻略
內存是Linux內核所管理的最重要的資源之一。內存管理系統是操作系統中最為重要的部分,因為系統的物理內存總是少於系統所需要的內存數量。虛擬內存就是為了克服這個矛盾而采用的策略。系統的虛擬內存通過在各個進程之間共享內存而使系統看起來有多於實際內存的內存容量。Linux支持虛擬內存, 就是使用磁盤作為RAM的擴展,使可用內存相應地有效擴大。核心把當前不用的內存塊存到硬盤,騰出內存給其他目的。當原來的內容又要使用時,再讀回內存。
一、內存使用情況監測
(1)實時監控內存使用情況
在命令行使用“Free”命令能夠監控內存使用情況
#free
total used free shared buffers cached
Mem: 256024 192284 63740 0 10676 101004
-/+ buffers/cache: 80604 175420
Swap: 522072 0 522072
上面給出了一個256兆的RAM和512兆交換空間的系統情況。第三行輸出(Mem:)顯示物理內存。total列不顯示核心使用的物理內存(通常大約1MB)。used列顯示被使用的內存總額(第二行不計緩沖)。 free列顯示全部沒使用的內存。Shared列顯示多個進程共享的內存總額。Buffers列顯示磁盤緩存的當前大小。第五行(Swap:)對對換空間,顯示的信息類似上面。假如這行為全0,那么沒使用對換空間。在缺省的狀態下,free命令以千字節(也就是1024字節為單位)來顯示內存使用情況。能夠使用?h參數以字節為單位顯示內存使用情況,或能夠使用?m參數以兆字節為單位顯示內存使用情況。還能夠通過?s參數使用命令來不間斷地監控內存使用情況:
#free ?b ?s2
這個命令將會在終端窗口中連續不斷地報告內存的使用情況,每2秒鍾更新一次。
(2)組合watch? free命令用來實時監控內存使用情況:
#watch -n 2 -d free
Every 2.0s: free Fri Jul 6 06:06:12 2007
total used free shared buffers cached
Mem: 233356 218616 14740 0 5560 64784
-/+ buffers/cache: 148272 85084
Swap: 622584 6656 615928
watch命令會每兩秒執行 free一次,執行前會清除屏幕,在同樣位置顯示數據。因為 watch命令不會卷動屏幕,所以適合出長時間的監測內存使用率。能夠使用 -n選項,控制執行的頻率;也能夠利用 -d選項,讓命令將每次不同的地方顯示出來。Watch命令會一直執行,直到您按下 [Ctrl]-[C] 為止。
二、虛擬內存的概念
(1)Linux虛擬內存實現機制
Linux虛擬內存的實現需要六種機制的支持:地址映射機制、內存分配回收機制、緩存和刷新機制、請求頁機制、交換機制、內存共享機制。
首先內存管理程式通過映射機制把用戶程式的邏輯地址映射到物理地址,在用戶程式運行時假如發現程式中要用的虛地址沒有對應的物理內存時,就發出了請求頁需要;假如有空閑的內存可供分配,就請求分配內存(於是用到了內存的分配和回收),並把正在使用的物理頁記錄在緩存中(使用了緩存機制)。 假如沒有足夠的內存可供分配,那么就調用交換機制,騰出一部分內存。另外在地址映射中要通過TLB(翻譯后援存儲器)來尋找物理頁;交換機制中也要用到交換緩存,並且把物理頁內容交換到交換文檔中后也要修改頁表來映射文檔地址。
(2)虛擬內存容量設定
也許有人告訴您,應該分配2倍於物理內存的虛擬內存,但這是個不固定的規律。假如您的物理保存比較小,能夠這樣設定。假如您有1G物理內存或更多的話,能夠縮小一下虛擬內存。Linux會把大量的內存用做Cache的,但在資源緊張時回收回.。您只要看到swap為0或很小就能夠放心了,因為內存放着不用才是最大的浪費。
三、使甩vmstat命令監控虛擬內存使用情況
vmstat是Virtual Meomory Statistics(虛擬內存統計)的縮寫,可對操作系統的虛擬內存、進程、CPU活動進行監控。他是對系統的整體情況進行統計,不足之處是無法對某個進程進行深入分析。通常使用vmstat 5 5(表示在5秒時間內進行5次采樣)命令測試。將得到一個數據匯總他能夠反映真正的系統情況。
#vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 62792 3460 9116 88092 6 30 189 89 1061 569 17 28 54 2
0 0 62792 3400 9124 88092 0 0 0 14 884 434 4 14 81 0
0 0 62792 3400 9132 88092 0 0 0 14 877 424 4 15 81 0
1 0 62792 3400 9140 88092 0 0 0 14 868 418 6 20 74 0
1 0 62792 3400 9148 88092 0 0 0 15 847 400 9 25 67 0
vmstat命令輸出分成六個部分:
(1)進程procs:
r:在運行隊列中等待的進程數 。
b:在等待io的進程數 。
(2)內存memoy:
swpd:現時可用的交換內存(單位KB)。
free:空閑的內存(單位KB)。
buff: 緩沖去中的內存數(單位:KB)。
cache:被用來做為高速緩存的內存數(單位:KB)。
(3) swap交換頁面
si: 從磁盤交換到內存的交換頁數量,單位:KB/秒。
so: 從內存交換到磁盤的交換頁數量,單位:KB/秒。
(4) io塊設備:
bi: 發送到塊設備的塊數,單位:塊/秒。
bo: 從塊設備接收到的塊數,單位:塊/秒。
(5)system系統:
in: 每秒的中斷數,包括時鍾中斷。
cs: 每秒的環境(上下文)轉換次數。
(6)cpu中央處理器:
cs:用戶進程使用的時間 。以百分比表示。
sy:系統進程使用的時間。 以百分比表示。
id:中央處理器的空閑時間 。以百分比表示。
假如 r經常大於 4 ,且id經常小於40,表示中央處理器的負荷很重。 假如bi,bo 長期不等於0,表示物理內存容量太小。
四、Linux 服務器的內存泄露和回收內存的方法
1、內存泄漏的定義:
一般我們常說的內存泄漏是指堆內存的泄漏。堆內存是指程式從堆中分配的,大小任意的(內存塊的大小能夠在程式運行期決定),使用完后必須顯示釋放的內存。應用程式一般使用malloc,realloc,new等函數從堆中分配到一塊內存,使用完后,程式必須負責相應的調用free或delete釋放該內存塊,否則,這塊內存就不能被再次使用,我們就說這塊內存泄漏了。
2、內存泄露的危害
從用戶使用程式的角度來看,內存泄漏本身不會產生什么危害,作為一般的用戶,根本感覺不到內存泄漏的存在。真正有危害的是內存泄漏的堆積,這會最終消耗盡系統任何的內存。從這個角度來說,一次性內存泄漏並沒有什么危害,因為他不會堆積,而隱式內存泄漏危害性則很大,因為較之於常發性和偶發性內存泄漏他更難被檢測到。存在內存泄漏問題的程式除了會占用更多的內存外,還會使程式的性能急劇下降。對於服務器而言,假如出現這種情況,即使系統不崩潰,也會嚴重影響使用。
3、內存泄露的檢測和回收
對於內存溢出之類的麻煩可能大家在編寫指針比較多的復雜的程式的時候就會碰到。在 Linux 或 unix 下,C、C++語言是最使用工具。但是我們的 C++ 程式缺乏相應的手段來檢測內存信息,而只能使用 top 指令觀察進程的動態內存總額。而且程式退出時,我們無法獲知任何內存泄漏信息。
使用kill命令
使用Linux命令回收內存,我們能夠使用Ps、Kill兩個命令檢測內存使用情況和進行回收。在使用終極用戶權限時使用命令“Ps”,他會列出任何正在運行的程式名稱,和對應的進程號(PID)。Kill命令的工作原理是:向Linux操作系統的內核送出一個系統操作信號和程式的進程號(PID)。
應用例子:
為了高效率回收內存能夠使用命令ps 參數v:
[root@www ~]# ps v
PID TTY STAT TIME MAJFL TRS DRS RSS %MEM COMMAND
2542 tty1 Ss+ 0:00 0 8 1627 428 0.1 /sbin/mingetty tty1
2543 tty2 Ss+ 0:00 0 8 1631 428 0.1 /sbin/mingetty tty2
2547 tty3 Ss+ 0:00 0 8 1631 432 0.1 /sbin/mingetty tty3
2548 tty4 Ss+ 0:00 0 8 1627 428 0.1 /sbin/mingetty tty4
2574 tty5 Ss+ 0:00 0 8 1631 432 0.1 /sbin/mingetty tty5
2587 tty6 Ss+ 0:00 0 8 1627 424 0.1 /sbin/mingetty tty6
2657 tty7 Ss+ 1:18 12 1710 29981 7040 3.0 /usr/bin/Xorg :0 -br -a
2670 pts/2 Ss 0:01 2 682 6213 1496 0.6 -bash
3008 pts/4 Ss 0:00 2 682 6221 1472 0.6 /bin/bash
3029 pts/4 S+ 0:00 2 32 1783 548 0.2 ping 192.168.1.12
3030 pts/2 R+ 0:00 2 73 5134 768 0.3 ps v
然后假如想回收Ping命令的內存的話,使用命令:
# Kill -9 3029
Linux中Cache內存占用過高解決辦法
在Linux系統中,我們經常用free命令來查看系統內存的使用狀態。在一個RHEL6的系統上,free命令的顯示內容大概是這樣一個狀態:

這里的默認顯示單位是kb,我的服務器是128G內存,所以數字顯得比較大。這個命令幾乎是每一個使用過Linux的人必會的命令,但越是這樣的命令,似乎真正明白的人越少(我是說比例越少)。一般情況下,對此命令輸出的理解可以分這幾個層次:
-
不了解。這樣的人的第一反應是:天啊,內存用了好多,70個多G,可是我幾乎沒有運行什么大程序啊?為什么會這樣?Linux好占內存!
-
自以為很了解。這樣的人一般評估過會說:嗯,根據我專業的眼光看的出來,內存才用了17G左右,還有很多剩余內存可用。buffers/cache占用的較多,說明系統中有進程曾經讀寫過文件,但是不要緊,這部分內存是當空閑來用的。
-
真的很了解。這種人的反應反而讓人感覺最不懂Linux,他們的反應是:free顯示的是這樣,好吧我知道了。神馬?你問我這些內存夠不夠,我當然不知道啦!我特么怎么知道你程序怎么寫的?
根據目前網絡上技術文檔的內容,我相信絕大多數了解一點Linux的人應該處在第二種層次。大家普遍認為,buffers和cached所占用的內存空間是可以在內存壓力較大的時候被釋放當做空閑空間用的。但真的是這樣么?在論證這個題目之前,我們先簡要介紹一下buffers和cached是什么意思:
什么是buffer/cache?
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。
明白了這兩套緩存系統的區別,就可以理解它們究竟都可以用來做什么了。
什么是page cache?
Page cache主要用來作為文件系統上的文件數據的緩存來用,尤其是針對當進程對文件有read/write操作的時候。如果你仔細想想的話,作為可以映射文件到內存的系統調用:mmap是不是很自然的也應該用到page cache?在當前的系統實現里,page cache也被作為其它文件類型的緩存設備來用,所以事實上page cache也負責了大部分的塊設備文件的緩存工作。
什么是buffer cache
Buffer cache則主要是設計用來在系統對塊設備進行讀寫的時候,對塊進行數據緩存的系統來使用。這意味着某些對塊的操作會使用buffer cache進行緩存,比如我們在格式化文件系統的時候。一般情況下兩個緩存系統是一起配合使用的,比如當我們對一個文件進行寫操作的時候,page cache的內容會被改變,而buffer cache則可以用來將page標記為不同的緩沖區,並記錄是哪一個緩沖區被修改了。這樣,內核在后續執行臟數據的回寫(writeback)時,就不用將整個page寫回,而只需要寫回修改的部分即可。
如何回收cache?
Linux內核會在內存將要耗盡的時候,觸發內存回收的工作,以便釋放出內存給急需內存的進程使用。一般情況下,這個操作中主要的內存釋放都來自於對buffer/cache的釋放。尤其是被使用更多的cache空間。既然它主要用來做緩存,只是在內存夠用的時候加快進程對文件的讀寫速度,那么在內存壓力較大的情況下,當然有必要清空釋放cache,作為free空間分給相關進程使用。所以一般情況下,我們認為buffer/cache空間可以被釋放,這個理解是正確的。
但是這種清緩存的工作也並不是沒有成本。理解cache是干什么的就可以明白清緩存必須保證cache中的數據跟對應文件中的數據一致,才能對cache進行釋放。所以伴隨着cache清除的行為的,一般都是系統IO飆高。因為內核要對比cache中的數據和對應硬盤文件上的數據是否一致,如果不一致需要寫回,之后才能回收。
在系統中除了內存將被耗盡的時候可以清緩存以外,我們還可以使用下面這個文件來人工觸發緩存清除的操作:
[root@tencent64 ~]# cat /proc/sys/vm/drop_caches 1
方法是:
echo 1 > /proc/sys/vm/drop_caches
當然,這個文件可以設置的值分別為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分配器中的緩存對象。
優化后截圖如下:
使用命令查看磁盤IO:
iostat -x 2
查看CPU使用IO:
top
iotop命令:
[root@node105 ~]# yum -y install iotop
CPU 過高處理辦法
load average 是對 CPU 負載的評估,其值越高,說明其任務隊列越長,處於等待執行的任務越多。出現此種情況時,可能是由於僵死進程導致的。可以通過指令 ps -axjf 查看是否存在 D 狀態進程。
D 狀態是指不可中斷的睡眠狀態。該狀態的進程無法被 kill,也無法自行退出。只能通過恢復其依賴的資源或者重啟系統來解決。

