文章目录

  • Java内存溢出故障案例及Linux内存机制探究
  • OOM Killer触发机制分析
  • 如何避免系统触发OOM Killer

这部分内容属于demo案例分享,解决线上运维问题,思路是最重要的

Java内存溢出故障案例及Linux内存机制探究

这是一个线上数据分析应用故障案例,电话告警说分析任务失败,此数据分析程序是基于Java的,运行在一台CentOS6.x版本的操作系统上。作为一个经验丰富的运维老手,第1步是尝试是否能够远程SSH登录到系统,还好,SSH还能够远程连接。笔者首先怀疑是应用程序本身的问题,因为它在崩溃之前一点异常也没有。于是笔者查看了应用程序日志,没有错误,没有警告,也没有任何可疑的信息。看来问题好像不在程序代码上,那么就尝试从操作系统方面看看是否有可疑日志信息。果然在5min后,笔者通过执行dmesg命令的时候,发现了如下异常信息:

此日志对排查问题非常有用,从这里可以发现其实是Linux内核的问题,是OOM Killer(Out of memory Killer)kill了PID为30328的Java进程,而这个进程刚好是线上数据分析应用对应的进程。那么OOM Killer为什么要kill掉Java进程呢,这个要详细分析一下。

此日志对排查问题非常有用,从这里可以发现其实是Linux内核的问题,是OOM Killer(Out of memory Killer)kill了PID为30328的Java进程,而这个进程刚好是线上数据分析应用对应的进程。那么OOM Killer为什么要kill掉Java进程呢,这个要详细分析一下。要解决问题,找到关键的日志非常重要,上面第1步已经找到了异常日志,那么下面就来分析一下这些日志中都包含了哪些信息,理解了这些日志的含义,处理问题的方法也就很容易找到了。首先看到有个Out of memory关键字,很明显,这是内存溢出的标志,这通常是因为某时刻应用程序大量请求内存导致系统内存不足造成的,继而触发了Linux内核里的内存不足终结者Out of Memory(OOM)killer的内建机制。在内存过低的情况下,这个终结者会被激活,然后挑选出一个进程去终结掉,以腾出内存留给系统用,不至于让系统立刻崩溃。其实,从日志中也可以看出,是内存不够了,可以看到有Free swap=0kB的字样,另外还有oom_adj、oom_score_adj等值也均为0,这些值的含义,下面会做详细介绍。

最后,从日志中可知,此系统环境是2.6.32-431.el6.x86_64,其实是CentOS6.5x86_64版本的系统。先看看系统内存状态,从free看,可用物理内存很低,cached和buffers都比较低:

再观察系统message日志,跟dmesg命令获取的信息完全吻合

到这里为止,基本可以确定是系统内存不足,导致出现了这次故障,但是,为什么系统内存突然会占用完呢?为什么OOM Killer要kill掉这个数据分析的Java进程而不是其他进程?

OOM Killer触发机制分析

OOM Killer是Linux内核在内存不足情况下的一种管理机制,当内核检测到系统物理内存不足时,就会通过OOM Killer机制kill掉一些进程。kill进程的原则是通过使用一套启发式算法计算所有进程的分数,然后选出分数最高的那个进程kill掉。一般分数最高的进程占用的内存刚好是最大的。那么为什么会突然出现内存不足的情况呢?这就要说说进程与内存的运行机制。默认情况下,Linux内核根据应用程序的要求分配内存,通常来说应用程序分配了内存但是实际上并没有全部使用,为了提高性能,这部分没用的内存可以留作他用。这部分内存是属于每个进程的,内核直接回收利用的话比较麻烦,所以内核采用一种过度分配内存(over-commit memory)的办法来间接利用这部分“空闲”的内存,提高整体内存的使用效率。这个问题最类似的就是宽带运营商了,如现在电信宽带承诺卖给用户的都是300MB光纤带宽,而这实际上远远超出了他们的网络容量。他们赌的就是用户实际上并不会同时使用并用完分配的带宽上限。

一般来说这样做没有问题,但当大多数应用程序都消耗完自己的内存的时候麻烦就来了,如果这些应用程序的内存需求加起来超出了物理内存(包括Swap)的容量,这就会导致系统可用内存迅速降低甚至不够用的情况,也就是没有内存页能够再分配给进程了。此时,内核必须kill掉一些进程才能腾出内存空间保障系统正常运行,于是,OOM Killer机制被激活了,并通过启发式算法找出了要终结的进程。

理解了这个机制之后,就很容易理解了为什么Java进程“躺着也能中枪”了,因为它在系统上一般占用内存最多,所以如果发生Out of Memeory(OOM)的话,Java进程总是不幸第1个被kill掉的应用。OOM Killer机制也是可配置的,可以通过一些内核参数来调整OOM Killer的行为,避免系统在那里不停地kill进程。kill进程是根据每个进程打分的高低来决定的,root权限的进程通常被认为很重要,不应该被轻易kill掉,所以打分的时候可以得到3%的优势。运维人员可以在用户空间通过操作每个进程的oom_adj内核参数来降低哪些进程被OOM Killer选中kill掉的概率。例如,如果不想Java进程被轻易kill掉的话,可以找到Java运行的进程号后,调整oom_score_adj的值即可

如何避免系统触发OOM Killer

通过上面的分析解读已经知道发生了什么问题,但还是搞不清楚到底是谁触发了OOM Killer。通过进一步的了解和分析,找到了答案:这个数据分析应用系统,每天定时分析的数据量在9000万左右,而故障的当天,要分析的数据量在5亿左右,数据量的陡增,导致分析程序占用大量内存,进而出现内存资源不足,所以数据量增大是导致触发OOM Killer的直接原因。

此外,查看系统/proc/sys/vm/overcommit_memory的设置

cat /proc/sys/vm/overcommit_memory

此值为1,表示用户申请内存的时候,系统不会对内存是否够用进行检查,这样,就会出现内存超过可用内存的情况,进而触发OOM Killer,这也是此次事故的另一个原因。要尽量避免OOM Killer的产生,可以设置/proc/sys/vm/overcommit_memory为0,这样,可以最大限度地避免系统触发OOM Killer。

end…

Java内存溢出故障案例及Linux内存机制探究相关推荐

  1. java堆外内存溢出_JVM 案例 - 堆外内存导致的溢出错误

    案例 一个网站为了实现客户端实时从服务端接收数据,使用了 CometD 1.1.1 作为服务端推送框架,服务器是 Jetty7.1.4,CPU i5,内存 4G,操作系统 32位Windows. 服务 ...

  2. python 内存溢出能捕获吗_Python内存泄漏和内存溢出的解决方案

    一.内存泄漏 像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题. 对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是 ...

  3. linux cma机制探究

    Linux cma机制探究 cma的作用    cma,全称(contiguous memory allocation),在内存初始化时预留一块连续内存,可以在内存碎片化严重时通过调用dma_allo ...

  4. Java反序列化json内存溢出_fastJson与一起堆内存溢出'血案'

    现象 QA同学反映登录不上服务器 排查问题1–日志级别 查看log,发现玩家登录的时候抛出了一个java.lang.OutOfMemoryError 大概代码是向Redis序列化一个PlayerMir ...

  5. java内存溢出原因及解决_java内存溢出的原因和解决方法

    java内存溢出的原因和解决方法 发布时间:2020-06-15 17:57:39 来源:亿速云 阅读:85 作者:元一 内存溢出含义: 内存溢出(out of memory)通俗理解就是内存不够,通 ...

  6. jvm性能调优实战 -59数据同步系统频繁OOM内存溢出故障排查

    文章目录 背景 从现象看到本质 通过jstat来确认我们的推断 通过MAT找到占用内存最大的对象 背景 首先说一下案例背景,线上有一个数据同步系统,是专门负责从另外一个系统去同步数据的,简单来说,另外 ...

  7. java内存溢出怎样查找代码_JVM - 内存溢出,问题查找

    当内存溢出会抛出 java.lang.OutOfMemoryError: Java heap space 的异常,那这个时候怎样去分析到底哪里导致内存溢出呢? 我们可以通过在vm的参数, -XX:+H ...

  8. java模拟内存溢出并分析_模拟内存溢出通过MAT分析

    构建一个简单的Springboot应用,模拟出OOM场景,再导出heap dump文件,通过Mat分析. 搭建简易Springboot,模拟OOM场景 搭建一个简易的springboot工程,在con ...

  9. 瑞萨RL78系列单片机报内存溢出故障的解决过程。RA78K0R error E3206: Segment ‘@@CODEL‘ can‘t allocate to memory - ignored

    最近开始使用瑞萨的R7F0C908芯片,ROM48K,对于目前的项目肯定是足够了,虽知道代码完成后,编译出现这个故障:RA78K0R error E3206: Segment '@@CODEL' ca ...

最新文章

  1. android系统密码设置功能,手机锁屏密码怎么设置 三种安卓手机锁屏方式推荐
  2. Python数据可视化——使用Matplotlib创建散点图
  3. 中国计算机与信息服务贸易,中国计算机与信息服务贸易国际竞争力研究
  4. python 字典键值重复_浅谈python字典多键值及重复键值的使用
  5. linux共享内存变量 tiaojianbianliang,修改linux共享内存大小
  6. [react-router] React-Router怎么设置重定向?
  7. Redis发布订阅模式
  8. 计算机应用杂志投稿,计算机类杂志 (可网上投稿)
  9. 小白也能看得懂的服务端性能测试指标及问题排查
  10. JAVA中的“抽象接口”
  11. Oh-My-Zsh 下远程ssh的乱码问题
  12. Cache-control
  13. python定时重启程序
  14. Android设备运用Clockworkmod Recovery恢复模式安装定制的Rom
  15. 小米nfc模拟加密门禁卡详细图文教程(实测可用)----------------- IC ID CUID卡区别
  16. win10没有indexed文件_不止用来切程序,Win10任务栏还能这么玩
  17. 不吹不黑!逛 GitHub 没看过这 10 个开源项目,绝对血亏...
  18. k折交叉验证KFold()函数
  19. java反序列化成object_java 反序列化输出 object获取为空的问题
  20. Webservice-2

热门文章

  1. 架构(一) - 架构的意义
  2. 2021年茶艺师(初级)考试及茶艺师(初级)报名考试
  3. React学习笔记_shoping_cart
  4. 有道云笔记MarkDown插入图片
  5. 定积分的计算(牛顿-莱布尼茨公式)习题
  6. pyspark基础学习——数据处理
  7. 携程酒店数据爬取2020.5
  8. JAVA 设计模式—————— 命令模式和职责链模式
  9. 简易天体运动—— sun earth moon(计算机图形学)
  10. uni-app 109生成个人二维码名片