版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/qq2430/article/details/82319958
概述
jstack [ options ] pid
- options:命令行选项
- pid:进程ID
jstack命令可以用来查看线程堆栈。根据堆栈信息我们可以定位程序出现的问题,例如CPU偏高等问题。本文使用的是JDK10,不同版本间可能存在差异。
options
不添加options的时候,默认查看线程堆栈信息
[root@izbp1chtb8a3vd2mzvuawlz target]# jstack 13969|more
2018-09-02 22:01:27
Full thread dump Java HotSpot(TM) 64-Bit Server VM (10.0.2+13 mixed mode):
Threads class SMR info:
_java_thread_list=0x00007fc06c0014f0, length=31, elements={
0x00007fc0a00af800, 0x00007fc0a00b2000, 0x00007fc0a00c6800, 0x00007fc0a00c8000,
0x00007fc0a00ca000, 0x00007fc0a00cb800, 0x00007fc0a0148000, 0x00007fc0a0152800,
0x00007fc0a0b1e800, 0x00007fc0a071a000, 0x00007fc0a0552000, 0x00007fc0a08a3800,
0x00007fc0a07f7800, 0x00007fc0a07a5000, 0x00007fc0a05fd800, 0x00007fc0a09dd800,
0x00007fc0a06c6800, 0x00007fc0a0a41800, 0x00007fc0a0a3e000, 0x00007fc0a0795800,
0x00007fc0a04b7800, 0x00007fc0a05eb000, 0x00007fc0a0246000, 0x00007fc0a0769000,
0x00007fc0a000f000, 0x00007fc05c3df800, 0x00007fc05c3ef800, 0x00007fc05c3f0800,
0x00007fc05c142000, 0x00007fc05c143800, 0x00007fc06c002800
}
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007fc0a00af800 nid=0x3694 waiting on condition [0x00007fc085265000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@10.0.2/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@10.0.2/Reference.java:174)
at java.lang.ref.Reference.access$000(java.base@10.0.2/Reference.java:44)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@10.0.2/Reference.java:138)
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007fc0a00b2000 nid=0x3695 in Object.wait() [0x00007fc085164000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(java.base@10.0.2/Native Method)
- waiting on <0x00000000f5bc0938> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@10.0.2/ReferenceQueue.java:151)
- waiting to re-lock in wait() <0x00000000f5bc0938> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@10.0.2/ReferenceQueue.java:172)
at java.lang.ref.Finalizer$FinalizerThread.run(java.base@10.0.2/Finalizer.java:216)
"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007fc0a00c6800 nid=0x3696 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007fc0a00c8000 nid=0x3697 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task
-l:输出有关锁的其他信息。
[root@izbp1chtb8a3vd2mzvuawlz target]# jstack -l 13969|more
2018-09-02 21:58:28
Full thread dump Java HotSpot(TM) 64-Bit Server VM (10.0.2+13 mixed mode):
Threads class SMR info:
_java_thread_list=0x00007fc06c0014f0, length=31, elements={
0x00007fc0a00af800, 0x00007fc0a00b2000, 0x00007fc0a00c6800, 0x00007fc0a00c8000,
0x00007fc0a00ca000, 0x00007fc0a00cb800, 0x00007fc0a0148000, 0x00007fc0a0152800,
0x00007fc0a0b1e800, 0x00007fc0a071a000, 0x00007fc0a0552000, 0x00007fc0a08a3800,
0x00007fc0a07f7800, 0x00007fc0a07a5000, 0x00007fc0a05fd800, 0x00007fc0a09dd800,
0x00007fc0a06c6800, 0x00007fc0a0a41800, 0x00007fc0a0a3e000, 0x00007fc0a0795800,
0x00007fc0a04b7800, 0x00007fc0a05eb000, 0x00007fc0a0246000, 0x00007fc0a0769000,
0x00007fc0a000f000, 0x00007fc05c3df800, 0x00007fc05c3ef800, 0x00007fc05c3f0800,
0x00007fc05c142000, 0x00007fc05c143800, 0x00007fc06c002800
}
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007fc0a00af800 nid=0x3694 waiting on condition [0x00007fc085265000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@10.0.2/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@10.0.2/Reference.java:174)
at java.lang.ref.Reference.access$000(java.base@10.0.2/Reference.java:44)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@10.0.2/Reference.java:138)
Locked ownable synchronizers:
- None
"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007fc0a00b2000 nid=0x3695 in Object.wait() [0x00007fc085164000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(java.base@10.0.2/Native Method)
- waiting on <0x00000000f5bc0938> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@10.0.2/ReferenceQueue.java:151)
- waiting to re-lock in wait() <0x00000000f5bc0938> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@10.0.2/ReferenceQueue.java:172)
at java.lang.ref.Finalizer$FinalizerThread.run(java.base@10.0.2/Finalizer.java:216)
Locked ownable synchronizers:
- None
-h | -help:输出帮助信息。
[root@izbp1chtb8a3vd2mzvuawlz target]# jstack -h
Usage:
jstack [-l] <pid>
(to connect to running process)
Options:
-l long listing. Prints additional information about locks
-h or -help to print this help message
使用示例
1 首先我们使用top命令,查看cpu偏高的进程,可以看到13969的进程cpu利用率已经到达99.3%
[root@izbp1chtb8a3vd2mzvuawlz target]# top
top - 22:03:23 up 6 days, 1:10, 1 user, load average: 1.02, 1.31, 1.40
Tasks: 68 total, 1 running, 67 sleeping, 0 stopped, 0 zombie
%Cpu(s):100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1015440 total, 315900 free, 407956 used, 291584 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 450064 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
13969 root 20 0 2518236 141388 17068 S 99.3 13.9 42:38.25 java
936 root 20 0 292652 13668 1512 S 0.3 1.3 6:20.00 docker-containe
1160 root 20 0 65372 2144 1728 S 0.3 0.2 3:16.37 aliyun-service
14336 root 20 0 161956 2208 1552 R 0.3 0.2 0:00.02 top
1 root 20 0 43536 3084 1872 S 0.0 0.3 0:05.53 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:01.90 ksoftirqd/0
2 然后使用jstack命令将线程堆栈输出到文件中
[root@izbp1chtb8a3vd2mzvuawlz /]# jstack 13969 > 13969.stack
[root@izbp1chtb8a3vd2mzvuawlz /]# ls
13969.stack bin boot config dev etc heap.bin home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
3 使用top -Hp查看哪个线程的cpu利用率偏高
[root@izbp1chtb8a3vd2mzvuawlz /]# top -Hp 13969
top - 22:07:13 up 6 days, 1:14, 1 user, load average: 1.79, 1.39, 1.40
Threads: 34 total, 1 running, 33 sleeping, 0 stopped, 0 zombie
%Cpu(s):100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1015440 total, 315916 free, 407856 used, 291668 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 450164 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
14021 root 20 0 2518236 141388 17068 R 99.7 13.9 46:15.79 pool-1-thread-1
13980 root 20 0 2518236 141388 17068 S 0.3 13.9 0:01.35 VM Periodic Tas
13969 root 20 0 2518236 141388 17068 S 0.0 13.9 0:00.00 java
13970 root 20 0 2518236 141388 17068 S 0.0 13.9 0:02.77 java
13971 root 20 0 2518236 141388 17068 S 0.0 13.9 0:00.61 VM Thread
13972 root 20 0 2518236 141388 17068 S 0.0 13.9 0:00.00 Reference Handl
13973 root 20 0 2518236 141388 17068 S 0.0 13.9 0:00.00 Finalizer
13974 root 20 0 2518236 141388 17068 S 0.0 13.9 0:00.00 Signal Dispatch
13975 root 20 0 2518236 141388 17068 S 0.0 13.9 0:02.96 C2 CompilerThre
13976 root 20 0 2518236 141388 17068 S 0.0 13.9 0:01.34 C1 CompilerThre
4 如上文所式,14021这个线程的cpu利用率最高,我们将14021转换为16进制。
[root@izbp1chtb8a3vd2mzvuawlz /]# printf '%x\n' 14021
36c5
5 打开刚才保存的stack文件,搜索36c5,可以看到是StackAnalysisService的loop方法导致的,线程的状态RUNNABLE,其余线程都在都在等待这个线程释放锁。
...skipping...
"pool-1-thread-1" #33 prio=5 os_prio=0 tid=0x00007fc05c3df800 nid=0x36c5 runnable [0x00007fc084133000]
java.lang.Thread.State: RUNNABLE
at com.zs.study.analysis.service.StackAnalysisService.loop(StackAnalysisService.java:17)
at com.zs.study.analysis.service.StackAnalysisService.run(StackAnalysisService.java:9)
- locked <0x00000000f0a82680> (a com.zs.study.analysis.service.StackAnalysisService)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@10.0.2/ThreadPoolExecutor.java:1135)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@10.0.2/ThreadPoolExecutor.java:635)
at java.lang.Thread.run(java.base@10.0.2/Thread.java:844)
"pool-1-thread-2" #34 prio=5 os_prio=0 tid=0x00007fc05c3ef800 nid=0x36c6 waiting for monitor entry [0x00007fc0637d8000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.zs.study.analysis.service.StackAnalysisService.run(StackAnalysisService.java:9)
- waiting to lock <0x00000000f0a82680> (a com.zs.study.analysis.service.StackAnalysisService)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@10.0.2/ThreadPoolExecutor.java:1135)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@10.0.2/ThreadPoolExecutor.java:635)
at java.lang.Thread.run(java.base@10.0.2/Thread.java:844)