一、概述
1. 各種特性的頁
l free:空閑頁,該頁可立即被申請使用
l inactive clean:資料已經被寫到磁盤,資料還保留一份在記憶體,需回收該頁。
l Inactive dirty:髒頁,頁面不可用,頁面内容已經被修改但未寫入到磁盤,必須将頁内容寫到磁盤,回收該記憶體。當磁盤資訊比頁面裡緩存資訊更新時,這頁就叫髒頁,必須回收該記憶體。
2. 統計程序在使用過程中,有多少頁面可申請,有多少頁是髒頁
l 統計腳本
[root@station9 ~]# vim memory.sh
#!/bin/bash
cat /proc/$1/smaps | awk '
BEGIN { print "Execute before processing input";}
/* process input */
/Shared_Clean/{ CLEAN += $2; }
/Shared_Dirty/{ DIRTY += $2; }
END {
/* execute after processing input */
print "Shared_Clean: " CLEAN;
print "Shared_Dirty: " DIRTY;
}'
l 查詢測試
[root@station9 ~]# ./memory.sh 10892
Execute before processing input
Shared_Clean: 664 #可申請的記憶體
Shared_Dirty: 0 #髒頁數
二、回收dirty pages
1. pdflush程序
pdflush程序負責将記憶體資訊和磁盤資訊及時同步,回收髒頁,預設至少2個程序。
l [root@station9 ~]# ps -ef|grep pdflush
root 251 19 0 Aug18 ? 00:00:00 [pdflush]
root 252 19 0 Aug18 ? 00:00:00 [pdflush]
2. Tuning pdfulsh
l [root@station9 ~]# sysctl -a |grep vm.nr_pdflush_threads
<b>vm.nr_pdflush_threads</b> = 2
#pdflush程序數,當系統繁忙或記憶體較小時,适合寫大一些,但相對來說會導緻下次讀取較慢。預設情況,系統會根據磁盤IO的狀态,自動調整pdflush數。
l [root@station9 ~]# sysctl -a |grep dirty
<b>vm.dirty_expire_centisecs</b> = 2999
#機關(1%秒)當髒頁在記憶體的時間到達30秒(2999/100)時,pdflush回收髒頁。
<b>vm.dirty_writeback_centisecs</b> = 499
#機關(1%秒)預設pdfush每5s(499/100)去監控髒頁存活時間。
<b>vm.dirty_ratio</b> = 30
#程序産生的髒頁到達整個記憶體的百分比(30%)時,無需pdflush,程序自行回收髒頁。
<b>vm.dirty_background_ratio</b> = 7
#髒頁達到整個記憶體的百分比(7%)時使用,pdflush開始工作,回收髒頁。
三、回收clean pages
1. 送出所有髒頁buffer和pages
l <b>sync</b> 強制同步
l <b>echo s > /proc/sysrq-trigger</b>
<b></b>
[root@station9 ~]# ./memory.sh
Shared_Clean: 860
Shared_Dirty: 8
[root@station9 ~]# echo "s" > /proc/sysrq-trigger
Shared_Dirty: 0
2. 回收clean pages
l <b>echo 3 > /proc/sys/vm/drop_caches</b>
[root@station9 ~]# free -m
total used free shared buffers cached
Mem: 4054 600 3453 0 115 325
-/+ buffers/cache: 159 3895
Swap: 8189 0 8189
[root@station9 ~]# echo 3 > /proc/sys/vm/drop_caches
Mem: 4054 162 3891 0 0 20
-/+ buffers/cache: 141 3913
四、Out-of-memory killer(OOM,記憶體耗盡,自動kill适當程序機制)
1. 需要kill processes的情況
l 所有記憶體(包括swamp)被用完
l zone_normal内沒有可用頁
l 頁面表内無可用記憶體
2. 強制保留程序不能被殺死
l 高睡眠程序(該程序消耗記憶體較少)
l 通過/proc/pid/oom_score參數(可豁免kill的級别)判斷
3. 調OOM policy
l 開啟oom-kill功能
[root@station9 ~]# sysctl -a|grep oom
<b>vm.panic_on_oom </b>= 0
#0關閉,1開啟
l 保護oom-kill級别
<b>echo n >/proc/pid/oom_adj </b>
#-17<=n<=15,值越小程序被殺的可能行就越小
[root@station9 ~]# echo "vm.panic_on_oom = 1" >>/etc/sysctl.conf
[root@station9 ~]# sysctl -p
[root@station9 ~]# echo -17>/proc/10892/oom_adj
[root@station9 ~]# more /proc/10892/oom_adj
-17
[root@station9 ~]# more /proc/10892/oom_score
[root@station9 ~]# echo 15 >/proc/10892/oom_adj
[root@station9 ~]# cat /proc/10892/oom_score
1212416
#oom_score值随oom_adj自動變化無需設定,該值越大程序被殺死的機率越大,告訴表示程序被殺死的機率為2的1212416次方。
l 手動模拟oom-kill
[root@memory ~]#echo f > /proc/sysrq-trigger
#模拟oom-kill,通過/var/log/messages顯示,不會真正殺死程序,隻是模拟效果。
[root@memory ~]#tail -f /etc/log/messages
#檢視系統日志,可以顯示oom-kill程序。
4. 注意選項
l 殺父程序會同時殺死其子程序
l selinux版本:selinux-policy-targeted-2.4.6-106.el5_1.3 or late
l oom-kill隻能解決記憶體溢出(記憶體耗完),不能解決記憶體洩漏(應用程式造成記憶體無法回收)
五、Memory leaks(記憶體洩漏)
1. 兩種記憶體洩漏:
l virtual:應用程式請求時無法使用虛拟位址空間(vsize)
l real:沒有可用free記憶體(rss)
2. 檢視系統中記憶體回收情況
[root@station10 ~]# sar -R 1 120 #每秒檢視一次,檢視120次
Linux 2.6.18-194.el5 (station10) 2011年08月30日
00時09分44秒 frmpg/s bufpg/s campg/s
00時09分45秒 0.00 0.00 0.00
00時09分46秒 2.00 0.00 0.00
00時09分47秒 0.00 0.00 0.00
00時09分48秒 -252.00 0.00 0.00
00時09分49秒 126.73 1.98 -1.98
#frmpg/s:每秒中系統回收的記憶體頁數(頁:4k),負數:記憶體被占用;正數:記憶體回收。
#bufpg/s:每秒中系統回收的buffer頁數(頁:4k),負數:記憶體被占用;正數:記憶體回收
#campg/s:每秒中系統回收的cache頁數(頁:4k),負數:記憶體被占用;正數:記憶體回收
3. 觀察程序使用記憶體情況
[root@www ~]# watch -n 1 "ps axo pid,comm,rss,vsize|grep httpd"
Every 1.0s: ps axo pid,comm,rss,vsize|grep httpd Mon Aug 29 17:00:24 2011
10609 httpd 9404 27972
10675 httpd 4496 27972
10676 httpd 4496 27972
10677 httpd 4496 27972
10678 httpd 4496 27972
10679 httpd 4496 27972
10680 httpd 4496 27972
10681 httpd 4496 27972
10682 httpd 4496 27972
#rss:實體記憶體使用(kb)
#vsize:虛拟記憶體使用(kb)
4. 檢視程序記憶體洩漏情況
<b>valgrind --tool=memcheck cat /proc/$$/maps</b>
[root@www ~]#ls -ls
[root@www ~]# valgrind --tool=memcheck /proc/$$/maps
......
==10726== LEAK SUMMARY:
==10726== definitely lost: 0 bytes in 0 blocks
==10726== indirectly lost: 0 bytes in 0 blocks
==10726== possibly lost: 0 bytes in 0 blocks
==10726== still reachable: 13,400 bytes in 38 blocks
==10726== suppressed: 0 bytes in 0 blocks
==10726== Rerun with --leak-check=full to see details of leaked memory
本文轉自netsword 51CTO部落格,原文連結:http://blog.51cto.com/netsword/654899