jstack 次要用来查看某个过程内线程的堆栈信息
一个死锁的模仿代码
package test;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* @className: test
* @description: TODO 类形容
* @author: mac
* @date: 2020/12/3
**/
public class test {public static Executor executor=Executors.newFixedThreadPool(5);
public static Object lock=new Object();
public static void main(String[] args) {Task task1=new Task();
Task task2=new Task();
executor.execute(task1);
executor.execute(task2);
}
static class Task implements Runnable{
@Override
public void run() {synchronized (lock){calc();
}
}
private void calc() {
int n=0;
for(;;){n++;}
}
}
}
top 查看零碎中最耗资源的 java 过程 pid
> top
3913 root 20 0 6751200 18888 10452 S 100.3 0.1 0:20.71 java
3494 root 20 0 750324 46036 16564 S 0.7 0.3 48:31.49 containerd
4773 root 20 0 577428 33312 10540 S 0.7 0.2 77:03.92 jdog-kunlunmirr
23139 prometh+ 20 0 1559032 117636 28908 S 0.7 0.7 32:40.89 prometheus
1 root 20 0 191144 4132 2648 S 0.3 0.0 10:33.95 systemd
找出上一步 pid 内最耗 cpu 的线程 pid
> top -Hp 3913
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3929 root 20 0 6751200 18888 10452 R 99.7 0.1 0:59.54 java
3913 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3914 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.03 java
3915 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3916 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3917 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3918 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3919 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3920 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3922 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3923 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3924 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3925 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3926 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3927 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.00 java
3928 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.01 java
3930 root 20 0 6751200 18888 10452 S 0.0 0.1 0:00.01 java
计算该线程的 pid 的十六进制
> printf "%x\n" 3929
f59
定位代码
> jstack 3913 | grep f59 -A 50
"pool-1-thread-1" #9 prio=5 os_prio=0 tid=0x00007f88bc100000 nid=0xf59 runnable [0x00007f88a8a42000]
java.lang.Thread.State: RUNNABLE
at test.test$Task.calc(test.java:35)
at test.test$Task.run(test.java:28)
- locked <0x000000076d45d8d8> (a java.lang.Object)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"Service Thread" #8 daemon prio=9 os_prio=0 tid=0x00007f88bc0da800 nid=0xf57 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007f88bc0bd800 nid=0xf56 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f88bc0bb800 nid=0xf55 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f88bc0b8800 nid=0xf54 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f88bc0b7000 nid=0xf53 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f88bc086000 nid=0xf52 in Object.wait() [0x00007f88a9149000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076d408ee0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x000000076d408ee0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f88bc081800 nid=0xf50 in Object.wait() [0x00007f88a924a000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076d406c00> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x000000076d406c00> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=0 tid=0x00007f88bc077800 nid=0xf4f runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f88bc01e800 nid=0xf4b runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f88bc020800 nid=0xf4c runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f88bc022000 nid=0xf4d runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f88bc024000 nid=0xf4e runnable
在 dump 文件中, 线程个别会存在上面几种状态
- RUNNABLE 线程处于执行中
- BLOCKED 线程被阻塞
- WAITING 线程正在期待