out of memory killer (oom-killer)

這裡有一篇對 OOM KILLER 的詳細說明 : 


原文作者:Eric Sisler <esisler westminster lib co us>


原文鏈接:http://www.redhat.com/archives/t ... ugust/msg00006.html


由於這個問題似乎在不同的郵件列表中出現,我已經將此消息張貼到紅帽一般性討論列表了,RHEL3(Taroon)和RHEL4(Nahant)列表。很抱歉我沒有時間來更早的發布它。


通常,在大內存(6Gb+)服務器上,out of memory killer (oom-killer)也會殺死進程。在很多case中,人們都困惑地報告說還有剩余內存的情況下,為何oom-killer還會殺死進程?現象是在 /var/log/messages 日誌中,有如下信息:


  Out of Memory: Killed process [PID] [process name].


在我自己的case中,我在VMware中升級了各個RHEL3到RHEL4,有1個16Gb內存的服務器,還是會被oom-killer殺死進程。不用說,這非常令人沮喪。


事實證明,這個問題的原因是low memory耗盡。引用Tom的話“內核使用low memory來跟蹤所有的內存分配,這樣的話一個16GB內存的系統比一個4GB內存的系統,需要消耗更多的low memory,可能有4倍之多。這種額外的壓力從你剛啟動系統那一刻就開始存在了,因為內核結構必須為潛在的跟蹤四倍多的內存分配而調整大小( The kernel uses low memory to track allocations of all memory thus a system with 16GB of memory will use significantly more low memory than a system with 4GB, perhaps as much as 4 times. This extra pressure happens from the moment you turn the system on before you do anything at all because the kernel structures have to be sized for the potential of tracking allocations in four times as much memory)”。
有兩種方法查看 low memory 和 high memory 的狀態:


# egrep 'High|Low' /proc/meminfo
HighTotal:     5111780 kB
HighFree:         1172 kB
LowTotal:       795688 kB
LowFree:         16788 kB


# free -lm
             total       used       free     shared    buffers     cached
Mem:          5769       5751         17          0          8       5267
Low:           777        760         16          0          0          0
High:         4991       4990          1          0          0          0
-/+ buffers/cache:        475       5293
Swap:         4773          0       4773




當low memory耗盡,不管high memory剩余多少,oom-killer都開始殺死進程,以保持系統的正常運轉。
有兩種方法解決這個問題:


1、如果可能,請升級到64位系統。


這是最好的解決辦法,因為所有的內存都將成為low memory。如果你在這種情況下耗盡了low memory,那就真的是out of memory了。


2、如果受限於必須使用32位系統,最好的解決辦法是使用hugemem內核。


這種內核以不同的方式分割low/high memory,而且在大多數情況下會提供足夠多的low memory到high memory的映射(This kernel splits low/high memory differently, and in most cases should provide enough low memory to map high memory)。在大多數案例中,這是一個很簡單的修復方法:安裝hugemem kernel RPM包,然後重啟即可。


如果運行hugemem內核也不可能,你可以嘗試將 /proc/sys/vm/lower_zone_protection 的值設置為250甚至更多。這將讓內核願意保護low memory,從而在分配內存時多考慮從high memory分配(This will cause the kernel to try to be more aggressive in defending the low zone from allocating memory that could potentially be allocated in the high memory zone.)。據我所知,此選項從2.6.x內核才開始可用。必要的是,您可能需要通過一些實驗來找到您系統環境中最適合的值。可以使用下面方法快速的設置和檢查改值:


  # cat /proc/sys/vm/lower_zone_protection
  # echo "250" > /proc/sys/vm/lower_zone_protection




在 /etc/sysctl.conf 中加入設置,以便啟動就生效:


  vm.lower_zone_protection = 250




作為最後的努力,你可以關閉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"




很抱歉啰嗦多了。我希望它能幫助到那些正在被該問題困擾的人們。


--Eric


翻譯完畢,有些句子實在難理解,把原文貼在後面了。


=========再引用些支付寶牛人的文字:==============


http://www.dbanotes.net/database ... ory_oom_killer.html


說白了 OOM Killer 就是一層保護機制,用於避免 Linux 在內存不足的時候不至於出太嚴重的問題,把無關緊要的進程殺掉,有些壯士斷腕的意思。


先要學習點老知識,在 32 位CPU 架構下尋址是有限制的。Linux 內核定義了三個區域:


# DMA: 0x00000000 -  0x00999999 (0 - 16 MB)
# LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB
# HighMem: 0x038000000 - <硬件特定>




LowMem 區 (也叫 NORMAL ZONE ) 一共 880 MB,而且不能改變(除非用 hugemem 內核)。對於高負載的系統,就可能因為 LowMem 利用不好而引發 OOM Killer 。一個可能原因是 LowFree 太少了,另外一個原因是 LowMem 裏都是碎片,請求不到連續的內存區域【根據我遇到的一個案例,一個猜想是 有些應用一次性請求比較大的內存,恰恰又是 880M 之內的,空閑的(LowFree)不夠大,就會觸發 OOM Killer 出來幹活】。檢查當前 LowFree 的值:


# cat /proc/meminfo |grep LowFree




檢查LowMem內存碎片:


# cat /proc/buddyinfo




上面這條命令要在 2.6 Kernel 環境下有效。據說使用 SysRq 的方式更好,不過 Hang 的時候再用吧。參見 Metalink Note:228203.1 。


根據一些文檔描述,OOM Killer 在 2.4 與 2.6 上表現是不一樣的。2.4 的版本中是把新進來(新申請內存)的進程殺掉。而 2.6 上是殺掉占用內存最厲害的進程(這是很危險的,很容易導致系統應用癱瘓)。


對於 RHEL 4 ,新增了一個參數: vm.lower_zone_protection 。這個參數默認的單位為 MB,默認 0 的時候,LowMem 為 16MB。建議設置 vm.lower_zone_protection = 200 甚至更大以避免 LowMem 區域的碎片,是絕對能解決這個問題的(這參數就是解決這個問題出來的)。


而對於 RHEL 3 (Kernel 2.4) 似乎沒什麽好辦法,一個是用 Hugemem 內核(天知道會不會引入新的毛病),一個是升級到 2.4.21-47 並且使用新的核心參數 vm.vm-defragment 控制碎片的數量。再就是使用 RHEL 4 (Kernel 2.6),這又繞回去了。說白了,如果遇到 OOM Killer ,基本上是低版本 Kernel 設計上有點缺陷。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值