-
线程死锁
-
死循环
当线程停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道线程的执行过程中在后台做了哪些事,在等待哪些资源造成的卡顿。
使用方法
命令格式
jstack [options]
options 参数说明
jstack的option参数并不多,真正用到的也就三个,接下来我们一个个介绍一下
–F:当线程挂起(Suspended)时,使用jstack -l pid命令是不会打印堆栈信息的,使用-F则可以强制输出线程堆栈;但是会停止但
–l:打印的信息除了堆栈外,还会显示锁的附加信息;
–m:同时输出java和C/C++的堆栈信息;在java的系统类库里面,有很多方法都是native修饰的,这些native修饰的方法你在java层面是看不到源码的,因为这些方法都是C/C++实现的;
状态说明
在线程的堆栈中,需要特别留意以下几种状态:
-
Deadlock: 死锁(重点关注)
-
Waiting on condition: 等待资源(重点关注)
-
Waiting on monitor entry : 等待获取监视器(重点关注)
-
Blocked :阻塞(重点关注)
-
Runnable :执行中
-
Suspended : 暂停
-
Object.wait()或 TIME_WAITING :对象等待中
-
Parked : 停止
no option 参数
不带option参数的命令
jstack 12771
打印结果如下
…忽略其他堆栈信息我们只关注main线程的堆栈
“main” #1 prio=5 os_prio=31 tid=0x00007fee9101a000 nid=0x2903 runnable [0x00007000085aa000]
java.lang.Thread.State: RUNNABLE
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:255)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
- locked <0x000000076ab1ead0> (a java.io.BufferedInputStream)
at com.test.Test.main(Test.java:12)
…忽略其他堆栈信息我们只关注main线程的堆栈
第一行各个单词的解析,
-
“main”:线程名称 。
-
prio:线程优先级
-
tid:指Java Thread id。
-
nid:指native线程的id。。
-
[0x00007000085aa000]:线程栈起始地址。
-l打印锁的附加信息
这里我们使用2个窗口,分别使用以下2个命令来测试
第一个窗口执行
jstack -l 12771
第二个窗口中执行
jstack 12771
通过2个窗口对比可以看到,加了-l的命令多打印了锁的信息;
导出堆栈文件
一般情况下,如果程序出错了, 都不会直接在生产环境的服务器上找错误,这个时候就可以用到一个非常实用的功能,将堆栈快照导出来,然后copy到别的电脑上看,命令如下
jstack -l 2289 > jstackDump.txt
执行后,就可以看到文件已经导出来了
通过cat命令可以看到,里面的内容和我们在命令行输出的内容是一样的
实战一 、 找出cpu占用最高的线程(linux系统)
首先我们准备好一个死循环的线程