jstack工具在jdk中,用于dump线程堆栈信息
使用方法:
1.先ps或者jps或者top找到java进程对应的PID
2.找到资源占用率高的线程id并将其转换为16进制
方法1:
ps H -eo lstart,cmd,tid,pid,%cpu| grep 15084
方法2:
top -H -p 15084
方法3:
pidstat -t -p 15084 1 1
3.将资源占用最大的线程号转换为16进制(3aed即为转换的16进制线程)
[root@master local]# printf “%x\n” 15085
3aed
4.使用jstack打印出进程的堆栈信息,输出到文件,找到对应的nid进行排查
jstack $PID > thread.log
线程的几种状态:
NEW: 线程刚创建
RUNNABLE: 线程正在运行或者就绪
WAITING: 线程正在等待某个信号
TIMED_WAITING: 也是等待某个信号,但是有超时时间
BLOCKED:表示有线程阻塞,或者求锁而不得
TERMINATED: 表示线程运行结束
一般而言,new和terminated一般不用关注,runnable状态的线程占用cpu,waiting、timed_waiting、blocked状态的线程不耗cpu。
进程卡的时候,也是会分不同情况的,有的是因为算法问题,代码效率低下等,这时去看线程的状态就是runnalbe的;
有的是因为锁竞争、资源池不足造成的,这种情况下线程状态往往是waiting、timed_waiting、blocked,而且这种情况是不占用cpu的,所以又是后会发现系统占用cup很低但是程序很卡,问题就是出现在这里。
可以搞个死循环验证一下: