記憶體是Linux核心所管理的最重要的資源之一。
記憶體管理系統是作業系統中 最為重要的部分,因為系統的實體記憶體總是少於系統所需要的記憶體數量。虛擬記憶體就是為了克服這個矛盾而採用的策略。系統的虛擬記憶體通過在各個進程之間共用內 存而使系統看起來有多於實際記憶體的記憶體容量。
Linux支援虛擬記憶體, 就是使用磁碟作為RAM的擴充,使可用記憶體相應地有效擴大。核心把當前不用的記憶體塊存到硬碟,騰出記憶體給其他目的。當原來的內容又要使用時,再讀回記憶體。
一、記憶體使用量情況監測
(1)即時監控記憶體使用量情況
在命令列使用“Free”命令可以監控記憶體使用量情況
#free
--------------------------------------------------------------------------------------------------------
total used free shared buffers cached
Mem: 8161244 8143540 17704 0 2364 862404
-/+ buffers/cache: 7278772 882472
Swap: 1020088 1014332 5756
--------------------------------------------------------------------------------------------------------
上面給出了一個256兆的RAM和512兆交換空間的 系統情況。第三行輸出(Mem:)顯示實體記憶體。total列不顯示核心使用的實體記憶體(通常大約1MB)。used列顯示被使用的記憶體總額(第二行不計 緩衝)。 free列顯示全部沒使用的記憶體。Shared列顯示多個進程共用的記憶體總額。Buffers列顯示磁碟緩衝的當前大小。第五行(Swap:)對對換空
間,顯示的資訊類似上面。如果這行為全0,那麼沒使用對換空間。在預設的狀態下,free命令以KB(也就是1024位元組為單位)來顯示記憶體使用量情況。 可以使用?h參數以位元組為單位顯示記憶體使用量情況,或者可以使用?m參數以MB為單位顯示記憶體使用量情況。還可以通過?s參數使用命令來不間斷地監視記憶體使 用情況:
#free -b -s2
這個命令將會在終端視窗中連續不斷地報告記憶體的使用方式,-b:單位為bytes,-s2:每2秒鐘更新一次。
(2)組合watch free命令用來即時監控記憶體使用量情況:
#watch -n 2 -d free
--------------------------------------------------------------------------------------------------------
Every 2.0s: free Fri Nov 20 10:34:39 2009
total used free shared buffers cached
Mem: 8161244 8143412 17832 0 2364 861928
-/+ buffers/cache: 7279120 882124
Swap: 1020088 1014332 5756
--------------------------------------------------------------------------------------------------------
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 1 10(表示每1秒刷一次,共刷10次)命令測試。將得到一個資料匯總它可以反映真正的系統情況。
#vmstat 1 10
--------------------------------------------------------------------------------------------------------
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 1014332 18800 2364 861248 0 0 48 72 0 0 1 0 98 1
0 0 1014332 18800 2364 861248 0 0 0 0 1130 1134 0 0 100 0
0 0 1014332 18800 2364 861248 0 0 0 128 1212 1158 0 0 100 0
0 0 1014332 18800 2364 861248 0 0 0 0 1130 1104 0 0 100 0
0 0 1014332 18800 2364 861248 0 0 0 0 1186 1104 0 0 100 0
0 0 1014332 18840 2364 861248 0 0 0 0 1135 1101 1 0 99 0
0 0 1014332 18840 2364 861248 0 0 0 0 1129 1039 0 0 100 0
0 0 1014332 18848 2364 861248 0 0 0 44 1202 1055 0 0 100 0
0 0 1014332 18848 2364 861248 0 0 0 0 1144 1090 0 0 100 0
0 0 1014332 18880 2364 861248 0 0 0 0 1194 1134 1 0 99 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中央處理器:
us:使用者進程使用的時間 。以百分比表示。
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
11514 pts/14 Ss 0:00 0 679 54456 40 0.0 /bin/bash
9898 pts/14 S+ 0:00 0 2377 67094 56 0.0 vim diff.txt
26007 pts/6 Ss+ 0:00 2 679 54452 580 0.0 -bash
6217 pts/8 Ss 0:00 0 679 54324 1020 0.0 -bash
17900 pts/3 Ss 0:00 0 679 54316 564 0.0 -bash
--------------------------------------------------------------------------------------------------------
然後如果想回收vim命令的記憶體的話,使用命令:
# Kill -9 9898
使用工具軟體
Memprof是一個非常具有吸引力且非常便於使用的軟體,它由Red Hat的Owen Talyor創立。這個工具是用於GNOME前端的Boehm-Demers-Weiser記憶體回收行程。這個工具直接就可以執行,並且其工作起來無需對原始碼進行任何修改。在程式執行時,這個工具會以圖形化的方式顯示記憶體的使用方式。
部分摘自:http://www.chinaz.com/Server/Linux/0926393Q2008.html
另一個參考
這幾天在學習研究shell指令碼,寫的一些記憶體監控指令碼程式。在沒有nagios監視軟體的情況下,只要伺服器能上互連網,就可通過發郵件的方式來提醒管理員系統記憶體的使用方式。
一、安裝linux下面的一個郵件用戶端msmtp軟體(類似於一個foxmail的工具)
1、下載安裝:http://downloads.sourceforge.net/msmtp/msmtp-1.4.16.tar.bz2?modtime=1217206451&big_mirror=0
# tar jxvf msmtp-1.4.16.tar.bz2
# cd msmtp-1.4.16
# ./configure --prefix=/usr/local/msmtp
# make
# make install
2、建立msmtp設定檔和記錄檔(host為郵件網域名稱,郵件使用者名test,密碼123456)
# vim ~/.msmtprc
account default host 126.com from test@126.com auth login user test password 123456 logfile ~/.msmtp.log # chmod 600 ~/.msmtprc
# touch ~/.msmtp.log
3、mutt安裝配置:(一般linux下有預設安裝mutt)
# vim ~/.muttrc
set sendmail="/usr/local/msmtp/bin/msmtp" set use_from=yes set realname="memory" set from=test@126.com set envelope_from=yes set rfc2047_parameters=yes set charset="utf-8"
4、郵件發送測試(-s郵件標題,-a表加附件)
# echo "郵件內容123456" | mutt -s "郵件標題測試郵件" -a /scripts/test.txt test@126.com
二、使用free命令監控系統記憶體:
1、使用free命令查看linux系統記憶體使用量情況:(以M為單位)
# free -m
(執行結果如下樣式)
total used free shared buffers cached
Mem: 3952 3414 538 0 168 484
-/+ buffers/cache: 2760 1191
Swap: 8191 86 8105
2、查看截取剩餘記憶體free的數值命令:
(1) 實體記憶體free值:# free -m | grep Mem | awk '{print $4}'
(2) 緩衝區的free值:# free -m | grep - | awk '{print $4}'
(3) Swap分區free值:# free -m | grep Swap | awk '{print $4}'
3、編寫記憶體監控的指令檔:
# vim /scripts/free-mem.sh
#!/bin/bash #使用free命令監控linux系統記憶體變化 #取系統目前時間(以追加的方式寫入檔案>>) date >> /scripts/date-time.txt #抓取實體記憶體free值(以追加的方式寫入檔案>>) echo Mem-free: `free -m | grep Mem | awk '{print $4}'`M >> /scripts/mem-free.txt #抓取緩衝區的free值(以追加的方式寫入檔案>>) echo buffers/cache-free: `free -m
| grep - | awk '{print $4}'`M >> /scripts/buffers-free.txt #抓取Swap分區free值(以追加的方式寫入檔案>>) echo Swap-free: `free -m | grep Swap | awk '{print $4}'`M >> /scripts/swap-free.txt #逐行串連上面的時間和記憶體相關行資料(每次重新寫入檔案>) paste /scripts/date-time.txt /scripts/mem-free.txt /scripts/buffers-free.txt
/scripts/swap-free.txt > /scripts/freemem.txt # chmod a+x /scripts/free-mem.sh
# /scripts/free-mem.sh
4、查看記憶體監控的結果檔案:
# cat /scripts/freemem.txt
5、編寫free結果檔案郵件發送指令碼:
# vim /scripts/sendmail-mem.sh
#!/bin/bash #把產生的freemem.txt檔案通過郵件發送給使用者 #提取本伺服器的IP地址資訊 IP=`ifconfig eth0 | grep "inet addr" | cut -f 2 -d ":" | cut -f 1 -d " "` #提取當前日期時間 today=`date -d "0 day" +%Y年%m月%d日` #發送記憶體監控結果郵件 echo "這是$IP伺服器$today的記憶體監控報告,請下載附件。" | mutt -s "$IP伺服器$today記憶體監控報告" -a /scripts/freemem.txt
test@126.com # chmod a+x /scripts/sendmail-mem.sh
三、監控系統交換分區swap的情況,當使用超過80%的時候發警示郵件:
# vim /scripts/swap-warning.sh
#!/bin/bash #提取本伺服器的IP地址資訊 IP=`ifconfig eth0 | grep "inet addr" | cut -f 2 -d ":" | cut -f 1 -d " "` #系統分配的交換分區總量 swap_total=`free -m | grep Swap | awk '{print $2}'` #當前剩餘的交換分區free大小 swap_free=`free -m | grep Swap | awk '{print $4}'` #當前已使用的交換分區used大小 swap_used=`free
-m | grep Swap | awk '{print $3}'` if ((swap_used != 0)); then #如果交換分區已被使用,則計算當前剩餘交換分區free所佔總量的百分比,用小數來表示,要在小數點前面補一個整數位0 swap_per=0`echo "scale=2;$swap_free/$swap_total" | bc` #設定交換分區的警示值為20%(即使用超過80%的時候警示)。 swap_warn=0.20 #當前剩餘交換分區百分比與警示值進行比較(當大於警示值(即剩餘20%以上)時會返回1,小於(即剩餘不足20%)時會返回0
) swap_now=`expr $swap_per \> $swap_warn` #如果當前交換分區使用超過80%(即剩餘小於20%,上面的傳回值等於0),立即發郵件警示 if (($swap_now == 0)); then echo "$IP伺服器swap交換分區只剩下$swap_free M 未使用,剩餘不足20%,使用率已經超過80%,請及時處理。" | mutt -s "$IP 伺服器記憶體警示" test@126.com fi fi # chmod a+x /scripts/swap-warning.sh
四、加入任務計劃:記憶體每十分鐘檢測一次,有警示則立即發郵件(十分鐘發一次),記憶體檢測結果郵件每天早上8點發一次
# crontab -e
http://shop104965075.taobao.com