jps -l
定位CPU高问题
1 | 1. 使用 top 定位到占用CPU高的进程PID |
top -Hp pid
top -Hp pid 可以查看某个进程的线程信息
-H 显示线程信息,-p指定pid
可以看到 线程 26096 已经运行了17个小时,将 26096 转化为 16进制:65f0;
[root@localhost ~]# printf “%x\n” 27565
线程 27565 对应的 16进制编码为:6bad
各字段含义
1 | 统计信息区前五行是系统整体的统计信息。第一行是任务队列信息,同 uptime 命令的执行结果。其内容如下: |
jstack pid
jstack 用法
1 | /opt/java8/bin/jstack |
使用 jstack 打印 进程 26080 的线程堆栈
jstack 26080 > aaa.log
正向推导
jstack 26080 | grep 6bad -A 30
线程 26080(16进制:6bad) 的线程堆栈如下:
各字段含义
- pool-1-thread-3:线程名;
- prio:应该是线程的优先级;
- os_prio:对应的操作系统的 线程优先级;
- tid:jvm 中 的线程id;
- nid: tid映射的操作系统中的线程id,非常有用,不过这里是用16进制的表示。可以通过 printf “%x\n” 十进制数字 查找一个十进制数字的十六进制表示;
- waiting for condition:等待资源ID;
- TIMED_WAITING:当前线程状态;
反向推导
同理,nid=0x6f44 对应的线程ID 为 28484:
top -Hp 26080 | grep 28484
jstack解析示例
0、线程状态
jstack dump 日志文件中,值得关注的线程状态有:
- 死锁,Deadlock(重点关注)
- 执行中,Runnable
- 等待资源,Waiting on condition(重点关注)
- 等待获取监视器,Waiting on monitor entry(重点关注)
- 暂停,Suspended
- 对象等待中,Object.wait() 或 TIMED_WAITING
- 阻塞,Blocked(重点关注)
- 停止,Parked
- pool-1-thread-3:线程名;
- prio:应该是线程的优先级;
- os_prio:对应的操作系统的 线程优先级;
- tid:jvm 中 的线程id;
- nid: tid映射的操作系统中的线程id,非常有用,不过这里是用16进制的表示。可以通过 printf “%x\n” 十进制数字 查找一个十进制数字的十六进制表示;
- waiting for condition:等待资源ID;
- TIMED_WAITING:当前线程状态;
1、Object.wait() + locked
1 | "Timer-0" #22 daemon prio=5 os_prio=0 tid=0x00007fc29cb23800 nid=0x65ff in Object.wait() [0x00007fc28474c000] |
- locked:线程拿到了 synchornized 锁 Object;
- Object.wait():线程调用了 wait(n),释放了锁,进入到
Wait Set
队列; - TIMED_WAITING:线程处于 TIMED_WAITING 状态;
2、waiting on condition
1 | "pool-1-thread-1" #19 prio=5 os_prio=0 tid=0x00007fc220003800 nid=0x65fa waiting on condition [0x00007fc2851bb000] |
- ConditionObject.await:线程调用了 Condition 的 await 方法,释放了锁,同时进入WAITING 状态;
- 线程在 等待 其他线程 使用 Condition.signal() 将它唤醒
3、runnable
1 | "1414013111@qtp-802771878-1 - Acceptor0 SocketConnector@0.0.0.0:8081" #21 prio=5 os_prio=0 tid=0x00007fc29cb14800 nid=0x65fe runnable [0x00007fc28484d000] |
RUNNABLE:线程处于可运行状态 或 正在运行;