Arthas问题排除案例
一、现象
(死循环)线上CPU100%
(内存无法回收)内存OOM,系统down掉
二、原因
(死循环)不断的进行加减操作、不断的死循环打印日志、不断的new对象
(内存溢出)不断的大量new对象,但不被回收,也可能不是死循环,但new出的对象无法被回收,导致内存溢出,最后系统down机
三、解决过程
一)死循环 CPU100%
1、启动arthas
2、查询cpu占用最高线程
thread
3、发现id为58的线程CPU占用最高,查询其调用链
thread 58
在这边我们可以发现在SimulateHashMap.getNode方法中卡住了,这时候我们基本就可以确定是因为死循环的问题
二)OOM
原因:大量的new对象无法被回收,最后导致老年代被塞满了,导致内存OOM,最后系统down掉
注意:有条件可以在OOM之前,通过Arthas的dashbord监控jvm年轻代老年代的变化,最后现象老年代99%,但是在出现OOM导致系统down掉后就观察不了了,这个现象只能在OOM之前观察到。
1. 开启 HeapDumpOnOutOfMemoryError
当系统因为OOM down机后,之前JVM线程被销毁,生成的大对象都不会继续存在,所以我们需要当系统出现OOM时,立即生成当时的dump文件 。
version: '3' services: myapp: image: your-java-app-image ports: - "8080:8080" command: > java -Xloggc:/var/log/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/gc.dump -Xms20M -Xmx20M -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC
2.分析dump文件
发生OOM后生成dump文件,通过C:\Program Files\Java\jdk1.8.0_281\bin\jvisualvm.exe来加载分析dump文件,看到堆dump中有大量之前 JdbcTemplate 对象,原因量大量的对象放在HaspMap中,导致栈结束后,对象无法被回收,导致OOM。
四、热部署
1、直接修改源java文件(或 jad 反编译后)
2、通过 mc编译回.class文件
3、通过 redefine 将.class文件进行热部署
4、最后再观察cpu问题,正常
五、排查死锁问题
1)命令行检查死锁(可以使用jstack快速进行死锁检查)
jps -l jstack -l 100460|grep "deadlock"
jstack -l 100460 导出堆栈信息,死锁信息就在最后
2)Arthas排查死锁
thread -b //找出阻塞其它线程的线程
找到死锁的线程id后就可以查看具体堆栈信息了