常言道常在河边走,那有不湿鞋。作为一名Java开发人员,遇到OutOfMemoryError那可是在正常不过了,无论是别人写的代码导致的,还是别人写的代码导致的,总之不是我干的,你把Git记录拍在我脸上也不是我干的。遇到OOM不要慌,看一下姜同学是怎么解决的。
鄙人认为,遇到OOM之后的的重点还是离线分析堆内存快照,其它的操作都是辅助。
没错他真的OOM了。
你的java应用在启动时设置如下JVM参数就可以在OOM时自动产生堆内存快照了。
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=log/dump/
shell
log/dump/下面就会出现你想要的对内存快照文件。
如果你运气不错的话虽oom了但是你的应用还没挂,那么你可以使用下面的方法获得一份内存快照。
可以使用ps命令查看应用的PID,当然你一可以top -c 排名第一的应用大概率还是你那个oom的应用。
jmap -dump:format=b,file=message-23973.hprof 23973
shell
23973就是上面的PID
到此为止如果你的程序已经挂了你直接跳到最后看如何离线分析堆快照吧。
如果你的程序还没挂,你还可以执行下面的命令查看一下jvm的信息,当然如下的方法也可以是日常巡检,人工也好脚本也罢的巡检内容。
jmap -dump pid
shell
可以看到除了新生代的to区包括老生代在内的区域都已经99%了。
关于如何堆栈信息的查看,我之前写过的一篇线上cpu使用率100%如何排查里面有更详细的jstack使用方法。
jstat -gcutil PID
shell
可以看到进行了2195此Full GC,并且从后面的时间看几乎全部的时间都在Full gc。
这里我采用的是JDK自带的jvisualvm进行分析。
找到你的JAVA_HOME打开它
当然你也可以在终端输入他的名字直接打开它,毕竟你已经把这个目录加到你的环境变量了。
点开文件里面有个装入。然后装入你拿到的堆内存快照。
可以看到下面的基本信息
看着这个异常的堆栈像是xxl-job的问题,不过不要慌,继续向下走。
排名第一的很明显是我们自己的类,感觉就要破案了。
点进去发现有个很大的oomMap,
找到自己的代码
这不就破案了吗。