kbytes时,需注意lowmem的值

今天在调整内核中的内存策略,有台机器是16G内存32位系统,将vm.min_free_kbytes值设定为物理内存的5%,也就是内存低于5%自动释放,跟其他机器一样,编辑好sysctl.conf后执行sysctl -p,结果悲剧的事发生了,服务器马上就宕机了,通知机房重启无果,单用户也无法进入,报Kernel panic - not syncing: Out of memory and no killable processes... ,只能赶到机房,用光盘启动救援模式,将刚才添加策略注销掉系统可以起来了。

不甘心再次尝试设定vm.min_free_kbytes值,sysctl -p 结果一样,最后将值设定为2%,没有问题,那问题肯定出在这个值上,查看messages,其中有记录kernel: 896MB LOWMEM available这么一句,貌似在其他系统中没看到过,就从他下手查找原因。

宕机原因:

vm.min_free_kbytes 设定值高于LowTotal 值,系统认为没有足够的lowmem,而触发OOM Killer,将进程强行杀掉。

具体分析:

系统中内存分为lowmem和highmem,其中lowmem为寻址内存,当lowmem耗尽时,系统会触动OOM Killer将多余进程杀掉来释放内存(2.6内核为杀掉占用内存最高的进程)

其中64位系统会将所有内存大小都划分到lowmem中,防止lowmem不够用,而32为系统是分开的,上限为896M左右,具体可通过 egrep 'High|Low' /proc/meminfo  命令查看

如果将vm.min_free_kbytes 的值设定大于LowTotal 的值,则系统会认为当前没有足够的内存而触发OOM Killer,直至将所有进程杀掉,重启无法启动也是因为当启动时刚启动一个进程,系统就认为内存不足而将其杀掉,导致无法启动

(已做实验,将vm.min_free_kbytes的值设定的比lowmem值大1都会触发OOM Killer)

简单的说也就是像大家用32位的XP,如果你是4G内存,系统也就只能认到3.5G,在32位的linux里,系统认为lowmem就是当前内存的大小,只要lowmem不够用就认为内存不够用了,就开始杀进程来释放,设定vm.min_free_kbytes也就让系统空闲出多少lowmem,所以设定值超出lowmem会出现异常。

所以,32位系统设定前要查看实际lowmem的大小,虽说上限是896M,但我这台16G的机器才700M多,具体什么原因那就是内核机制的事了,有空再做研究,现在知道是怎么死的就行了。

血的教训呀,像大内存的机器,以后还是用64位系统吧,32位真是会在你不知情的情况下出问题呀。

备注:网上资料说在一个32位系统中,物理内存越高,所消耗的lowmem越高,16G的服务器所消耗的将近是4G内存的4倍左右

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8f40aec39e94392a861e8eb313e2489c.html