jstack的主要作用是生成JVM当前时刻线程的快照(threaddump,即当前进程中所有线程的信息)。可以帮助定位程序中出现的问题,如长时间停顿,CPU占有率过高等问题,也可以看出哪些程序是守护线程,哪些程序是用户线程。
在命令行输出jstack即可看出相关帮助信息:
jstack的基本语法是:jstack [option] <pid>
- 如果jstack后面加了-l参数,那么就会打印一些关于锁的信息;
- pid就是进程的id;
这里运行下面这段代码查看线程快照:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34package dgb.test.concurrent; import java.lang.management.ManagementFactory; /** * @author Dongguabai * @date 2018/9/2 19:35 */ public class SuspendTest { public static void main(String[] args) throws InterruptedException { ChangeObjectThread c1 = new ChangeObjectThread("thread-1"); ChangeObjectThread c2 = new ChangeObjectThread("thread-2"); c1.start(); c2.start(); // Thread.sleep(1000); c1.resume(); c2.resume(); } public static class ChangeObjectThread extends Thread { public ChangeObjectThread(String name) { super(name); } @Override public void run() { System.out.println("线程【" + getName() + "】正在执行"); Thread.currentThread().suspend(); } } }
查看当前进程的PID(通过Java代码查看pid的方法可以参看:Java程序中获取当前进程的pid,也可以使用 jps 命令)后执行命令:jstack -l <PID>:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134C:UsersDongguabai>jstack -l 3572 //当前线程快照生成的时间 2018-09-02 20:11:42 //运行的时候的JRE的版本信息,这里是服务器端版本 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.65-b01 mixed mode): "DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x0000000002a49000 nid=0x4828 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None //这是是刚刚我们创建的线程,pri=5是线程的优先级(默认为5,数字越大优先级越高); //线程类型:线程分为守护线程 (daemon) 和非守护线程 (non-daemon) 两种,通常都是守护线程; //如果使用 java.lang.Thread 类生成一个线程的时候,线程名称为 Thread-(数字) 的形式; //tid是JVM线程的id:JVM内部线程的唯一标识,通过 java.lang.Thread.getId()获取,通常用自增的方式实现; //nid=0x395c系统线程id:对应的系统线程id(Native Thread ID),可以通过 top 命令进行查看,id是十六进制的形式;结合top H可以快速查看CPU占用过高的线程; "thread-2" #12 prio=5 os_prio=0 tid=0x0000000019543800 nid=0x395c runnable //0x000000001a1af000起始栈地址:线程堆栈调用的其实内存地址; [0x000000001a1af000] //RUNNABLE实线程的状态; java.lang.Thread.State: RUNNABLE //线程的RUNNABLE状态是由这个导致的; at java.lang.Thread.suspend0(Native Method) at java.lang.Thread.suspend(Thread.java:1029) at dgb.test.concurrent.SuspendTest$ChangeObjectThread.run(SuspendTest.java:32) //由于加了-l参数,所以会出现下面的消息;当前线程是否处于同步块内; Locked ownable synchronizers: - None "thread-1" #11 prio=5 os_prio=0 tid=0x0000000019542800 nid=0xcf0 runnable [0x000000001a0af000] java.lang.Thread.State: RUNNABLE at java.lang.Thread.suspend0(Native Method) at java.lang.Thread.suspend(Thread.java:1029) at dgb.test.concurrent.SuspendTest$ChangeObjectThread.run(SuspendTest.java:32) Locked ownable synchronizers: - None "Service Thread" #10 daemon prio=9 os_prio=0 tid=0x00000000194e6800 nid=0x471c runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "C1 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x00000000194cb800 nid=0x4b70 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000001946d000 nid=0x4508 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x0000000019469000 nid=0x1438 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x00000000193b2000 nid=0x4274 runnable [0x0000000019aae000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:170) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) - locked <0x00000000d650dfa0> (a java.io.InputStreamReader) at java.io.InputStreamReader.read(InputStreamReader.java:184) at java.io.BufferedReader.fill(BufferedReader.java:161) at java.io.BufferedReader.readLine(BufferedReader.java:324) - locked <0x00000000d650dfa0> (a java.io.InputStreamReader) at java.io.BufferedReader.readLine(BufferedReader.java:389) at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64) Locked ownable synchronizers: - None "Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000018bf3800 nid=0xe64 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000017850000 nid=0x4a00 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000002b39800 nid=0xb94 in Object.wait() [0x0000000018bae000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000d5f870b8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) - locked <0x00000000d5f870b8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) Locked ownable synchronizers: - None "Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000017819000 nid=0x3734 in Object.wait() [0x0000000018aaf000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000d5f86af8> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157) - locked <0x00000000d5f86af8> (a java.lang.ref.Reference$Lock) Locked ownable synchronizers: - None "VM Thread" os_prio=2 tid=0x0000000017817800 nid=0x4c8 runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002a5e800 nid=0x3860 runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002a60000 nid=0x4548 runnable "GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002a62000 nid=0x45d0 runnable "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002a63800 nid=0x2d1c runnable "VM Periodic Task Thread" os_prio=2 tid=0x000000001959e800 nid=0xaec waiting on condition JNI global references: 19
也可以使用:
复制代码
1jstack -l 1111 >1.txt
导出到 1.txt 文件。
最后
以上就是友好星星最近收集整理的关于jstack使用的全部内容,更多相关jstack使用内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复