同事在 Linux 服务器上遇到点小问题,我也上去折腾半天。这还是第一次注意到 Linux 这个比较多年就存在的特性: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 的值:
# cat /proc/meminfo |grep LowFree
检查LowMem内存碎片:
# cat /proc/buddyinfo
据说使用 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 控制碎片的数量。
其它,如果去查询 RedHat 的 Bug 库,会发现不少 Kernel 版本也有 Bug 的。尤其在使用 NFS 的场景。
--EOF--
头疼欲裂,零散记录点东西,备查。
Generator | Trampoline
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascr<script src="http://pagead2.googlesyndication.com/cpa/ads?client=ca-pub-2198040673582211&cpa_choice=caaqhat2_geaci52gvkp95-sklgsuiebmaa&oe=utf-8&dt=1211817239386&lmt=1211816952&format=ref_text&output=textlink&correlator=1211817239385&url=http%3a%2f%2fwww.dbanotes.net%2fdatabase%2flinux_outofmemory_oom_killer.html&region=_google_cpa_region_&ref=http%3a%2f%2fwww.dbanotes.net%2f&frm=0&cc=100&ga_vid=1671013206050389200.1211817239&ga_sid=1211817239&ga_hid=352680538&flash=9.0.64&u_h=800&u_w=1280&u_ah=772&u_aw=1280&u_cd=24&u_tz=480&u_his=1&u_nplug=3&u_nmime=4" language="javascript1.1" type="text/javascript"></script>type="text/javascript"> Get Firefox with Google Toolbar for better browsing
Generate revenue from your website. Google AdSense.