1. 死锁分析
死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象。
使用jstack工具,并且添加-l参数,利用工具检测死锁特性来发现死锁。
jstack -l <pid>
比如下面这样的线程堆栈信息就展示了死锁信息。
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007f0134003ae8 (object 0x00000007d6aa2c98, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x00007f0134006168 (object 0x00000007d6aa2ca8, a java.lang.Object),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at javaCommand.DeadLockclass.run(JStackDemo.java:40)
- waiting to lock <0x00000007d6aa2c98> (a java.lang.Object)
- locked <0x00000007d6aa2ca8> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
"Thread-0":
at javaCommand.DeadLockclass.run(JStackDemo.java:27)
- waiting to lock <0x00000007d6aa2ca8> (a java.lang.Object)
- locked <0x00000007d6aa2c98> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
Found 1 deadlock.
此外,还可以将所有的线程堆栈输出到文件中,然后对线程中的锁状态进行分析,查看是否存在多个线程等待同一个锁的情况,以及同一个锁出现在多个线程的情况。
2. 潜在问题分析
1. 如果某个相同的call stack经常出现,我们有80%的以上的理由确定这个代码存在性能问题(读网络的部分除外);
2. 如果相同的call stack出现在同一个线程上(tid)上, 我们很很大理由相信, 这段代码可能存在较多的循环或者死循环;
3. 如果某call stack经常出现, 并且里面带有lock,请检查一下这个lock的产生的原因, 可能是全局lock造成了性能问题;
4. 如果你怀疑有dead lock问题, 那么请把所有的lock id找出来,看看是不是出现重复的lock id。