在测试环境进行测试时,发现某个服务响应有一点点慢,于是ssh到对应环境,查看了一下cpu占用状况:
在应用top
指令之后 看到的后果是这样的
正如咱们所晓得的tomcat cpu 负载高 通常是:
1、代码问题:死循环、大量并发线程计算量大
2、full-gc : 有大对象产生、 对象援用无奈开释
于是试图应用jstack命令剖析问题
首先应用
jstack -l 119236 | grep 'java.lang.Thread.State' | wc -l
统计了一下线程数
能够看到一共有679个线程
而后又别离统计了
RUNNABLE线程数
jstack -l 119236 | grep 'java.lang.Thread.State: RUNNABLE' | wc -l
WAITING的线程数
jstack -l 119236 | grep 'java.lang.Thread.State: WAITING' | wc -l
TIMED_WAITING的线程数
jstack -l 119236 | grep 'java.lang.Thread.State: TIMED_WAITING' | wc -l
BLOCKED的线程数
jstack -l 119236 | grep 'java.lang.Thread.State:BLOCKED' | wc -l
以及死锁(deadlock)的线程数
jstack -l 119236 | grep 'Java-level deadlock' | wc -l
能够看到,一顿操作下来
咱们晓得了目前这个过程中 一共有 679个线程 其中有
79个线程处于RUNNABLE (线程运行中或I/O期待状态)
347个线程处于线程在WAITING (有限期待唤醒的状态)
66个线程在TIMED_WAITING (期待唤醒,但设置了时限的状态)
0个线程处于BLOCKED状态 (期待一个monitor lock的状态)
没有发现死锁
既然没有死锁 那咱们看看导致是哪些线程导致了占用高呢?
接下来咱们应用指令 查看过程119236中 占用最高的线程top -Hp 119236
咱们发现 这个122318占用十分高 达到了45%,于是咱们进一步将该线程的pid转为16进制输入printf "%x\n" 122318
随后应用
jstack 119236 |grep 1ddce -A 30
看到占用最高的线程的具体信息
发现只是redission的线程,作为一个分布式缓存锁,该线程cpu占用高属于失常状况
随后咱们应用jstat -gcutil 119236
查看该java过程的gc状况
能够看到在屡次间断的查问中YGC(Minor GC)的次数十分多,然而理论耗费的工夫还是比拟正当的。
如果各项参数设置正当,零碎没有超时日志呈现,GC频率不高,GC耗时不高,那么没有必要进行GC优化;如果GC工夫超过1〜3 秒,或者频繁G C ,则必须优化。如果满足上面的指标,则个别不须要进行GC:
■ Minor GC执行工夫不到50ms;
■ Minor GC执行不频繁,约10秒一次;
■ Full GC执行工夫不到1s;
所以本次理论从线程剖析和gc剖析的角度来看,服务并无异样,或者我该去看看接口,溜了溜了