一 jstack命令
1 | jstack -help |
示例:
1 | $ jps |
打开temp.log 可以看到所有线程的当前状态。
附线程状态表:
参考官网:https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr034.html#sthref31
| Thread State | Description |
|:————-:|:————-:|
| NEW | The thread has not yet started. |
| RUNNABLE | The thread is executing in the JVM. |
| BLOCKED | The thread is blocked waiting for a monitor lock. |
| WAITING | The thread is waiting indefinitely for another thread to perform a particular action. |
| TIMED_WAITING | The thread is waiting for another thread to perform an action for up to a specified waiting time. |
| TERMINATED | The thread has exited. |
二 实战死循环
先实现一段死循环代码
1 | "/loop") ( |
执行命令定位位置
1 | # top |
查看tmp.log中线程id为0x2976的线程
1 | "http-nio-8080-exec-1" #18 daemon prio=5 os_prio=0 tid=0x00007f9c7415e000 nid=0x2976 waiting on condition [0x00007f9c439fa000] |
则定位出来是因为UserController.loop方法出现的死循环
步骤说明:
- 通过top命令查询出占用cpu高的进程
- 根据进程ID执行命令 top -p [PID] -H 查看占用cpu最好的线程
- 把线程ID转16进制 printf “%x” 10614
- jstack查询进程ID的日志到文件
- 查询这个文件进程ID为转好的16进制线程ID,从而定位出哪里导致的cpu飙高的代码。
三 实战死锁
先模拟出一段死锁代码
1 | "/deadlock") ( |
通过jstack [PID] 查询
看到最后面有
1 | Found one Java-level deadlock: |
jstack已经帮我们找出了死锁的位置,更改修复即可。