歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux Out of Memory(OOM) Killer

Linux Out of Memory(OOM) Killer

日期:2017/2/27 15:59:38   编辑:Linux教程
Linux有一個特性:OOM Killer,一個保護機制,用於避免在內存不足的時候不至於出現嚴重問題,把一些無關的進程優先殺掉,即在內存嚴重不足時,系統為了繼續運轉,內核會挑選一個進程,將其殺掉,以釋放內存,緩解內存不足情況,不過這種保護是有限的,不能完全的保護進程的運行。
在很多情況下,經常會看到還有剩余內存時,oom-killer依舊把進程殺死了,現象是在/var/log/messages日志文件中有如下信息:
Out of Memory: Killed process [PID] [process name].
該問題是low memory耗盡,因為內核使用low memory來跟蹤所有的內存分配。
當low memory耗盡,不管high memory剩多少,oom-killer都會殺死進程,以保持系統的正常運行。
在32位CPU下尋址范圍是有限的,Linux內核定義了下面三個區域:

# DMA: 0x00000000 - 0x00999999 (0 - 16 MB)
# LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB
# HighMem: 0x038000000 - <硬件特定>
LowMem區(也叫NORMAL ZONE)共880MB,並且是固定不能變的(除非使用hugemem內核),對於高負荷的系統,可能因為LowMem使用不好而觸發了OOM Killer機制。因為內存分配是一個連續的區域,在此時,如果LowMem裡存在很多碎片或者LowFree太少,此時無法分配到一塊連續的內存區域,就觸發了OOM Killer。
查看當前LowFree值:
cat /proc/meminfo | grep LowFree
查看LowMem內存碎片:
cat /proc/buddyinfo
上面這命令需要在2.6內核才有效。
有如下方法可以解決該問題:
1、升級到64位系統,這是最好的方法,因為此時所有的內存都屬low memory,如此時提示out of memory,則真的是low memory耗盡,真的OOM了。
2、如必須使用32位系統,那麼可以使用hugemem內核,此時內核會以不同的方式分割low/high memory,而大多數情況下會提供足夠多的low memory至high memory的映射,此時很簡單的一個修復方法是可以安裝hugemem內核包,然後重啟。
3、如果hugemem內核也用不了,那麼我們可以嘗試將/proc/sys/vm/lower_zone_protection的值設為250或更大,可使用如下命令查看和設置該值:
cat /proc/sys/vm/lower_zone_protection
echo 250 > /proc/sys/vm/lower_zone_protection
或者可以修改/etc/sysctl.conf文件,以便重啟後生效,添加的內容如下:
vm.lower_zone_protection = 250
4、實在沒辦法,那麼我們把oom-killer關掉,不過該選項可能導致系統掛起,故要看實際情況使用。
查看當前的oom-killer的狀態:cat /proc/sys/vm/oom-kill
關閉/打開oom-killer:
echo "0" > /proc/sys/vm/oom-kill
echo "1" > /proc/sys/vm/oom-kill
或者直接加到/etc/sysctl.conf文件,內容如下:
vm.oom-kill = 0
此時,當進程被oom-killer嘗試殺死而沒有成功時,會把相關信息記錄到/var/log/messages文件中,信息如下:
"Would have oom-killed but /proc/sys/vm/oom-kill is disabled"
5、或者不把oom-killer關掉,只針對單一進程處理,把某個進程保護起來,此時,我們可以使用如下命令:
echo -17 > /proc/[pid]/oom_adj
/proc/[pid]/oom_adj中oom_adj的取值范圍是-17~15,當該值為-17時,系統將不會殺死指定pid的進程,而-16~15則會使得進程的/proc/[pid]/oom_adj值呈指數(K*2^n)形式遞增,即它們被殺掉的可能性呈指數遞增。針對init(進程號為1)這個進程,無論該值設為多少都不會被殺。
Copyright © Linux教程網 All Rights Reserved