线程CPU一直占用很高,导致服务出现的性能该如何排查
1、首先通过top命令查询到占用cpu负载过高的进程PID。
2、通过top -Hp ****(进程ID)找到负载过高的具体子线程TID。
3、将进程ID从10进制转换为16进制。通过jstack ***(线程ID) | grep 1bfe -A 30查看当前线程的执行情况。如果线程的运行状态Thread.state 一直都为runnable状态,那就证明这个线程是出现了一直在运行的异常问题,可以通过执行的路径找到异常的问题点。
JVM的FULL GC次数过多,导致CPU负载过高如何排查
1、一般如果出现FULL GC异常的问题也有可能会出现cpu负载过高的问题,所以可以先通过Top命令拿到具体出现的问题进程PID
2、通过jstat -gcuitil PID 1000 获取最近的1000条GC日志,拿到GC日志以后可以观察FULL GC是否异常,如果未出现次数过多的异常,便不是这个问题。
3、如果是这个异常的话,直接通过jmap -dump:live,format=b,file=heap.hprof PID 通过jmap导出jvm的快照日志
4、通过快照日志便可知道是否存在太多未被异常回收掉的对象,对象一直被使用,没有被gc回收掉。最终就会导致jvm内存被消耗殆尽
5、如果还是找不到异常的问题的话就可以通过jstat -gccause PID 1000,查询最近1000条的GC回收的原因是什么,因为在代码中手动的调用System.gc()也会出现在这里面。
服务存在假死,直接服务访问不了的问题排查
1、首先进行上面两个步骤的排查,如果上面两个步骤的排查都没办法找到问题,那可能就是代码存在特别大的问题。
2、首先找到出现问题的服务,迅速先保留下jvm的运行快照日志。通过上步骤的jmap。
3、通过jdk的自带工具jvisualvm或者Jprofiler去分析dump文件的线程运行情况
在这里插入图片描述
3、可以上到上面的图中分析出,当前这个线程在dubbo调用时调用了jedispool的getResource()方法去拿一个redis的连接,结果连接池的连接一直都被占用了,没有新的连接被释放,底层就会调用locksuport的park去自旋拿锁。一直拿不到锁就会导致所有去拿redis的链接的地方都会堵死在这里,出现服务假死的现象。