暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

干货 | 从OOM到 JVM致命错误崩溃

东方龙马 2019-03-08
2584
作者:付传淮 | 东方龙马(OLM)



导读

读OOM本质是程序程序申请内存过大,虚拟机无法满足我们,然后自杀了。OOM经常伴随Full GC,高JDBC, Pending User Request等一系列的问题内存溢出的案例数不胜数, 所以日常运维中我们需要尽量避免OOM的发生。



一般来说OOM会在标准输出日志中打印出这句话:

Exception in thread "main" java.lang.OutOfMemoryError:

本案例就从在标准输出日志中找到的一段话说起。


某企业的某新项目的测试环境机器上的部分节点总是出现内存溢出,为此,重启了测试环境的所有节点,庆幸状态有所缓解,可惜过不了多久又复现。因此,东方龙马工程师得知后第一时间协助排查此问题。


东方龙马的工程师首先登陆测试环境,通过ps命令查看这台机器的进程。发现,这台机器上的Java进程已经按照运维规范,增加了参数

-XX:+HeapDumpOnOutOfMemoryError


但是,在我们排查问题的过程中,并没有发现内存溢出后自动产生的内存快照文件。


反而发现了一个hs_error_pid.log的文件。hs_error_pid.log文件,代表JVM产生了致命错误,其中往往包含了虚拟机崩溃原因的重要信息。


对很多人来说,OOM和JVM致命错误所产生的崩溃,最终都是进程丢失,认为没什么不同。


但是其实对比下OOM和JVM致命错误崩溃两种场景。


OOM属于”自杀”,JVM无法承受工作压力(内存压力),进行了自我终结,在自杀前,它会留下一份”遗书”(内存快照文件),向世人展示自己所遭受的苦楚(内存压力的主要大对象),所以如果认真解析下内存快照的话,得到的信息是相当多的,我们也能进行更近一步的进行优化。


JVM致命错误崩溃,则是”死于意外”,它因为一些意料之外的原因(很多时候是JVM Bug,也有可能是一些JVM设计时没想到的奇葩情况。)所以,来不及留下非常详细的内容,我们只能从”案发的一些只言片语”,结合经验乃至源码,进行故障的诊断。


在hs_error_pid.log文件中存在如下信息:

# There is insufficient memory for the Java Runtime Environment to continue.

# Cannot create worker GC thread. Out of system resources.

# Possible reasons:

#   The system is out of physical RAM or swap space

#   In 32 bit mode, the process size limit was hit

# Possible solutions:

#   Reduce memory load on the system

#   Increase physical memory or swap space

#   Check if swap backing store is full

#   Use 64 bit Java on a 64 bit OS

#   Decrease Java heap size (-Xmx/-Xms)

#   Decrease number of Java threads

#   Decrease Java thread stack sizes (-Xss)

#   Set larger code cache with -XX:ReservedCodeCacheSize=

# This output file may be truncated or incomplete.

#

#  Out of Memory Error (workgroup.cpp:99), pid=7107, tid=0x00007f6fbd54a700

#


可以看到JVM致命崩溃的原因是无法创建GC工作线程。


而无法创建GC工作线程有多种原因,我们按照hs_error_pid.log文件中罗列的项进行逐项检查,发现主机的ulimit -u值很小。

 


东方龙马工程师写了一个定时的批处理文件,检查后端用户线程数,最终确定了,就是这个值,可能无法满足当前的线程需求,导致了无法创建新的线程,导致如果需要创建GC线程的时候无法创建GC线程,JVM崩溃。



产生OOM的报错,不一定是内存不够用,也可能是无法创建线程,无法回收内存。开发人员的代码质量会影响JVM运行,操作人员的奇葩操作会影响JVM运行,而系统的各项基础指标限制,更会影响JVM运行。


运维工程师不仅仅要关注软件自身的配置,对于可能限制软件的一些硬件配置,也要做到心中有数,这样在面对生产故障时,才能更快的定位解决问题。


往期干货推荐

案例 | 通过调整SCN值恢复数据库紧急故障

干货 | 最佳的数据库系统IO性能测试方法

案例 | ASM元数据之FST损坏的修复

案例 | 业务员的非常规操作OOM故障处理

案例 | 核心系统中间件Hibernate一级缓存导致内存溢出的故障诊断

案例 | 100G+表改造为分区表实施脚本

案例 | 操作系统故障~通过RAC删增节点修复集群

案例 | OLM助力信诚聚益的核心数据上云

案例 | logfile sync调优的最佳方案




|  北京    |    上海    |   广州    |   成都    |


4008-906-960


文章转载自东方龙马,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论