一次JVM OOM问题排查
Posted 猪杂汤饭
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一次JVM OOM问题排查相关的知识,希望对你有一定的参考价值。
项目出现java.lang.OutOfMemoryError:GC overhead limit exceeded
用jmap查看jvm 堆的情况(如下),发现年轻代的Eden Sapce和老年代的空间接近饱和,初步分析是由于老年代的空间无法回收,进而导致年轻代的空间积压,在”最后一根稻草“的作用下,发生out of memory error。
sudo jmap -heap pid(java进程id)
使用jmap dump出jvm堆信息,但导出jvm堆信息时失败,提示以下异常,并且导致tomcat重启了
Caused by: sun.jvm.hotspot.utilities.AssertionFailure:
can not get class data for sun/net/ExtendedOptionsImpl$$Lambda$10x00000007c01fe828
这是JDK的bug,详情见https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8073605。由于线上jdk版本问题,导致无法dump线上的JVM堆。既然代码有问题,那么在本地跑一下不也能定位问题吗?
将代码在本地跑起来,观察JVM 堆的情况,果不其然,在本地运行时,JVM老年代被使用的空间随着时间越来越多,此时将JVM 堆导出来。
jmap -dump:format=b,file=heap.bin pid(java进程id)
使用Eclipse Memory Analyzer打开heap.bin,对JVM堆进行分析。
找到内存泄漏的地方了,接下来就好办了。最后发现是队列中,出列的数量相对少于进列的数量,随着时间推移,导致队列中积压了大量数据,最终引发了OOM。
以上是关于一次JVM OOM问题排查的主要内容,如果未能解决你的问题,请参考以下文章