• Linux OOM 自动杀死进程



    问题描述:

    今天上班后,登录一台内网测试服务器,发现部分进程失踪 (Nginx/PHP-FPM/MySQL/Crond)。

    解决方法:

    1、首先启动这些进程,保证正常提供服务。

    2、查看服务器日志信息,排除故障。

    shell > less /var/log/messages-20160905
    
    Sep  3 05:31:10 localdomain kernel: Out of memory: Kill process 3145 (mysqld) score 33 or sacrifice child
    Sep  3 05:31:10 localdomain kernel: Killed process 3145, UID 804, (mysqld) total-vm:9170936kB, anon-rss:246880kB, file-rss:32kB
    
    Sep  3 05:40:41 localdomain kernel: Out of memory: Kill process 20889 (nginx) score 2 or sacrifice child
    Sep  3 05:40:41 localdomain kernel: Killed process 20889, UID 803, (nginx) total-vm:130256kB, anon-rss:216kB, file-rss:12kB

    3、发现类似的日志信息,上网查资料。

    4、资料显示,这是由于系统内存不足导致触发 Linux Kernel OOM(Out of memory killer)保护机制,将占用内存大的进程杀死,以保证系统正常运行。

    Sep  3 05:37:10 localdomain kernel: mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
    Sep  3 05:37:10 localdomain kernel: mysqld cpuset=/ mems_allowed=0-1
    
    Sep  3 05:39:30 localdomain kernel: crond invoked oom-killer: gfp_mask=0x84d0, order=0, oom_adj=0, oom_score_adj=0
    Sep  3 05:40:26 localdomain kernel: crond cpuset=/ mems_allowed=0-1
    
    Sep  3 05:40:36 localdomain kernel: php invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
    Sep  3 05:40:37 localdomain kernel: php cpuset=/ mems_allowed=0-1

    5、还发现一种情况,内存够用,但还是触发了 OOM 杀死进程。这里涉及到一个 Low Memory 的知识点。内核使用 Low Memory 来跟踪所有的内存分配。

    注意:只有在 32 位操作系统中才区分 Low Memory 与 High Memory ,64 位系统中 Low Memory 就是所有内存空间。

    shell > free -lm
                 total       used       free     shared    buffers     cached
    Mem:         11901       1039      10861          0         47        133
    Low:         11901       1039      10861
    High:            0          0          0
    -/+ buffers/cache:        858      11042
    Swap:         8191          2       8189

    # 可以看到:Low 大小跟总内存一样大,High 都为 0 。

    6、那该怎么办?

    > 增加内存、使用 64 位操作系统。

    > 合理配置内存空间,例如 PHP 加速器的缓存空间等,定期重启 PHP-FPM 进程。

    > 手动释放内存:sync; echo 3 > /proc/sys/vm/drop_caches

    > 使用 hugemem 内核,该内核以不同的方式分割 low/high memory ,而且多数情况下会提供足够多的 low memory 到 high memory 的映射。
      安装 hugemem kernel rpm 包,重启服务器即可。
     
    > 指定不杀死某进程:echo -17 > /proc/$(pidof mysqld)/oom_adj  # -17 为对该进程禁止使用 OOM

    > echo "vm.panic_on_oom = 1" >> /etc/sysctl.conf; sysctl -p   # 关闭 OOM ( 后两三种慎用吧 )

    sync; echo 3 > /proc/sys/vm/drop_caches

  • 相关阅读:
    万万没想到,JVM内存结构的面试题可以问的这么难?
    理解JVM运行时数据区域,看这一篇文章就够了
    JVM扫盲:虚拟机内存模型与高效并发
    Java虚拟机难?一文了解JVM
    一篇简单易懂的原理文章,让你把JVM玩弄与手掌之中
    简单理解:JVM为什么需要GC
    一文让你读懂Java类加载机制!
    JVM结构的简单梳理
    深入理解JVM的类加载
    BAT面试必问题系列:JVM的判断对象是否已死和四种垃圾回收算法总结
  • 原文地址:https://www.cnblogs.com/wangxiaoqiangs/p/5842713.html
Copyright © 2020-2023  润新知