滕州保利海德一共几期:OOM killer "Out of Memory: Killed process" SO...

来源:百度文库 编辑:偶看新闻 时间:2024/05/06 02:16:25

水平有限,这只是sealinger自己的笔记。

由于这个问题似乎在不同的邮件列表中出现,我已经将此消息张贴到红帽一般性讨论列表了,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/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耗尽,不管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

翻译完毕,有些句子实在难理解,把原文贴在后面了。

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

说白了 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 设计上有点缺陷。