Linux有趣的內核機制:OOM
What(什麼是OOM):
Linux下面有個非常特別的機制叫OOM killer(Out Of Memory killer),這個有趣的傢伙會在系統內存耗盡的情況下跳出來,選擇性的幹掉一些進程以求釋放一些內存。默認具體的記錄日誌是在/var/log/messages中,如果出現了Out of memory字樣,說明系統曾經出現過OOM!
When(什麼時候出現):
linux下允許程序申請比系統可用內存更多的內存,這個特性叫Overcommit。這樣做是出於優化系統考慮,因為不是所有的程序申請了內存就立刻使用的,當使用的時候說不定系統已經回收了一些資源了。不幸的是,當用到這個Overcommit給的內存的時候,系統還沒有資源的話,OOM killer就跳出來了。
參數/proc/sys/vm/overcommit_memory可以控制進程對內存過量使用的應對策略
1.overcommit_memory=0,這是預設值,表示內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,並把錯誤返回給應用進程。
2.overcommit_memory=1,表示內核允許分配所有的物理內存,而不會檢查當前的內存狀態如何,換句話說就是來者不拒。這種策略適合那些不能承受內存分配失敗的應用,比如某些科學計算應用。
3.overcommit_memory=2,表示系統所能分配的內存不會超過swap+RAM*係數(/proc/sys/vm /overcmmit_ratio,默認50%,你可以調整),如果這麼多資源已經用光,那麼後面任何嘗試申請內存的行為都會返回錯誤,這通常意味著此時沒法運行任何新程序。
How(系統會怎麼樣):
當然,如果觸發了OOM機制,系統會殺掉某些進程,那麼什麼進程會被處理掉呢?kernel提供給用戶態的/proc下的一些參數:
1./proc/[pid]/oom_adj,該pid進程被oom killer殺掉的權重,一般介於 [-17,15](具體具體權重的範圍需要查看內核確認)之間,越高的權重,意味著更可能被oom killer選中,-17表示禁止被kill掉。
通過2個步驟可以確認,具體權重的範圍:
uname -a查看Linux內核版本
進入/usr/src/kernels/內核版本/include/linux/oom.h確認具體的權重範圍
2./proc/[pid]/oom_score,當前該pid進程的被kill的分數,越高的分數意味著越可能被kill,這個數值是根據oom_adj運算(2?,n就是oom_adj的值)後的結果,本身oom_score是不能修改值。
下面的流程圖是out_of_memory的調用關係,觸發OOM時會調用__out_of_memory函數。
__out_of_memory函數主要做了兩件事:
1.調用select_bad_process函數選擇一個最優的進程殺掉
2.根據選擇的最優的進程,調用函數oom_kill_process,殺掉該進程。
So(我們能做什麼):
1.保護我們重要的進程,避免被處理掉
實例:
ps -efgrep GameServer(獲得重要進程的PID)
echo -17 > /proc/PID/oom_score_adj(輸入-17,禁止被OOM機制處理)
2.開啟OOM較為的保險機制
echo 「vm.panic_on_oom=2」 >> /etc/sysctl.conf
systcl -p
TAG:全球大搜羅 |