水平有限,這只是sealinger自己的筆記。
由于這個(gè)問(wèn)題似乎在不同的郵件列表中出現,我已經(jīng)將此消息張貼到紅帽一般性討論列表了,RHEL3(Taroon)和RHEL4(Nahant)列表。很抱歉我沒(méi)有時(shí)間來(lái)更早的發(fā)布它。
通常,在大內存(6Gb+)服務(wù)器上,out of memory killer (oom-killer)也會(huì )殺死進(jìn)程。在很多case中,人們都困惑地報告說(shuō)還有剩余內存的情況下,為何oom-killer還會(huì )殺死進(jìn)程?現象是在 /var/log/messages 日志中,有如下信息:
Out of Memory: Killed process [PID] [process name].
在我自己的case中,我在VMware中升級了各個(gè)RHEL3到RHEL4,有1個(gè)16Gb內存的服務(wù)器,還是會(huì )被oom-killer殺死進(jìn)程。不用說(shuō),這非常令人沮喪。
事實(shí)證明,這個(gè)問(wèn)題的原因是low memory耗盡。引用Tom的話(huà)“內核使用low memory來(lái)跟蹤所有的內存分配,這樣的話(huà)一個(gè)16GB內存的系統比一個(gè)4GB內存的系統,需要消耗更多的low memory,可能有4倍之多。這種額外的壓力從你剛啟動(dòng)系統那一刻就開(kāi)始存在了,因為內核結構必須為潛在的跟蹤四倍多的內存分配而調整大?。?nbsp;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)”。
# egrep 'High|Low' /proc/meminfoHighTotal: 5111780 kBHighFree: 1172 kBLowTotal: 795688 kBLowFree: 16788 kB# free -lmtotal used free shared buffers cachedMem: 5769 5751 17 0 8 5267Low: 777 760 16 0 0 0High: 4991 4990 1 0 0 0-/+ buffers/cache: 475 5293Swap: 4773 0 4773
這是最好的解決辦法,因為所有的內存都將成為low memory。如果你在這種情況下耗盡了low memory,那就真的是out of memory了。:-)
2、如果受限于必須使用32位系統,最好的解決辦法是使用hugemem內核。
這種內核以不同的方式分割low/high memory,而且在大多數情況下會(huì )提供足夠多的low memory到high memory的映射(This kernel splits low/high memory differently, and in most cases should provide enough low memory to map high memory)。在大多數案例中,這是一個(gè)很簡(jiǎn)單的修復方法:安裝hugemem kernel RPM包,然后重啟即可。
如果運行hugemem內核也不可能,你可以嘗試將 /proc/sys/vm/lower_zone_protection 的值設置為250甚至更多。這將讓內核愿意保護low memory,從而在分配內存時(shí)多考慮從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內核才開(kāi)始可用。必要的是,您可能需要通過(guò)一些實(shí)驗來(lái)找到您系統環(huán)境中最適合的值??梢允褂孟旅娣椒焖俚脑O置和檢查改值:
# cat /proc/sys/vm/lower_zone_protection# echo "250" > /proc/sys/vm/lower_zone_protection
vm.lower_zone_protection = 250
查看當前oom-killer的狀態(tài):
# cat /proc/sys/vm/oom-kill
# echo "0" > /proc/sys/vm/oom-kill# echo "1" > /proc/sys/vm/oom-kill
vm.oom-kill = 0
"Would have oom-killed but /proc/sys/vm/oom-kill is disabled"
--Eric
翻譯完畢,有些句子實(shí)在難理解,把原文貼在后面了。
=========再引用些支付寶牛人的文字:==============
說(shuō)白了 OOM Killer 就是一層保護機制,用于避免 Linux 在內存不足的時(shí)候不至于出太嚴重的問(wèn)題,把無(wú)關(guān)緊要的進(jìn)程殺掉,有些壯士斷腕的意思。
先要學(xué)習點(diǎn)老知識,在 32 位CPU 架構下尋址是有限制的。Linux 內核定義了三個(gè)區域:
# DMA: 0x00000000 - 0x00999999 (0 - 16 MB)# LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB# HighMem: 0x038000000 - <硬件特定>
# cat /proc/meminfo |grep LowFree
# cat /proc/buddyinfo
根據一些文檔描述,OOM Killer 在 2.4 與 2.6 上表現是不一樣的。2.4 的版本中是把新進(jìn)來(lái)(新申請內存)的進(jìn)程殺掉。而 2.6 上是殺掉占用內存最厲害的進(jìn)程(這是很危險的,很容易導致系統應用癱瘓)。
對于 RHEL 4 ,新增了一個(gè)參數: vm.lower_zone_protection 。這個(gè)參數默認的單位為 MB,默認 0 的時(shí)候,LowMem 為 16MB。建議設置 vm.lower_zone_protection = 200 甚至更大以避免 LowMem 區域的碎片,是絕對能解決這個(gè)問(wèn)題的(這參數就是解決這個(gè)問(wèn)題出來(lái)的)。
而對于 RHEL 3 (Kernel 2.4) 似乎沒(méi)什么好辦法,一個(gè)是用 Hugemem 內核(天知道會(huì )不會(huì )引入新的毛病),一個(gè)是升級到 2.4.21-47 并且使用新的核心參數 vm.vm-defragment 控制碎片的數量。再就是使用 RHEL 4 (Kernel 2.6),這又繞回去了。說(shuō)白了,如果遇到 OOM Killer ,基本上是低版本 Kernel 設計上有點(diǎn)缺陷。
聯(lián)系客服