Chinaunix首页 | 论坛 | 博客
  • 博客访问: 588085
  • 博文数量: 135
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1654
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-09 16:16
个人简介

围城

文章分类

全部博文(135)

文章存档

2019年(3)

2018年(7)

2017年(14)

2016年(15)

2015年(34)

2014年(9)

2013年(53)

我的朋友

分类: LINUX

2016-08-12 22:40:46

Linux有一个特性:OOM Killer,一个保护机制,用于避免在内存不足的时候不至于出现严重问题,把一些无关的进程优先杀掉,即在内存严重不足时,系统为了继续运转,内核会挑选一个进程,将其杀掉,以释放内存,缓解内存不足情况,不过这种保护是有限的,不能完全的保护进程的运行。
    在很多情况下,经常会看到还有剩余内存时,oom-killer依旧把进程杀死了,现象是在/var/log/messages日志文件中有如下信息:
    Out of Memory: Killed process [PID] [process name].
    该问题是low memory耗尽,因为内核使用low memory来跟踪所有的内存分配。
    当low memory耗尽,不管high memory剩多少,oom-killer都会杀死进程,以保持系统的正常运行。
    在32位CPU下寻址范围是有限的,Linux内核定义了下面三个区域:
 # DMA: 0x00000000 -  0x00999999 (0 - 16 MB) 

   # LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB

   # HighMem: 0x038000000 - <硬件特定> 
    LowMem区(也叫NORMAL ZONE)共880MB,并且是固定不能变的(除非使用hugemem内核),对于高负荷的系统,可能因为LowMem使用不好而触发了OOM Killer机制。因为内存分配是一个连续的区域,在此时,如果LowMem里存在很多碎片或者LowFree太少,此时无法分配到一块连续的内存区域,就触发了OOM Killer。
    查看当前LowFree值:
    cat /proc/meminfo | grep LowFree
    查看LowMem内存碎片:
    cat /proc/buddyinfo
    上面这命令需要在2.6内核才有效。
    有如下方法可以解决该问题:
    1、升级到64位系统,这是最好的方法,因为此时所有的内存都属low memory,如此时提示out of memory,则真的是low memory耗尽,真的OOM了。
    2、如必须使用32位系统,那么可以使用hugemem内核,此时内核会以不同的方式分割low/high memory,而大多数情况下会提供足够多的low memory至high memory的映射,此时很简单的一个修复方法是可以安装hugemem内核包,然后重启。
    3、如果hugemem内核也用不了,那么我们可以尝试将/proc/sys/vm/lower_zone_protection的值设为250或更大,可使用如下命令查看和设置该值:
       cat /proc/sys/vm/lower_zone_protection
       echo 250 > /proc/sys/vm/lower_zone_protection
       或者可以修改/etc/sysctl.conf文件,以便重启后生效,添加的内容如下:
       vm.lower_zone_protection = 250
    4、实在没办法,那么我们把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"
    5、或者不把oom-killer关掉,只针对单一进程处理,把某个进程保护起来,此时,我们可以使用如下命令:
       echo -17 > /proc/[pid]/oom_adj
       /proc/[pid]/oom_adj中oom_adj的取值范围是-17~15,当该值为-17时,系统将不会杀死指定pid的进程,而-16~15则会使得进程的/proc/[pid]/oom_adj值呈指数(K*2^n)形式递增,即它们被杀掉的可能性呈指数递增。针对init(进程号为1)这个进程,无论该值设为多少都不会被
阅读(1979) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~