共计 1249 个字符,预计需要花费 4 分钟才能阅读完成。
在测试环境进行测试时, 发现某个服务响应有一点点慢,于是 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 剖析的角度来看,服务并无异样, 或者我该去看看接口, 溜了溜了