jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。
线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。
root@cv-console-rds-68784cdf9c-zk4d8:/# jstack -help
Usage:
jstack [-l]
(to connect to running process)
jstack -F [-m] [-l]
(to connect to a hung process)
jstack [-m] [-l]
(to connect to a core file)
jstack [-m] [-l] [server_id@]
(to connect to a remote debug server)
Options:
-F to force a thread dump. Use when jstack does not respond (process is hung)
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
-h or -help to print this help message
-l参数
如果使用-l参数,除了方法栈帧以外,jstack命令还会显示关于锁的附加信息,比如属于java.util.concurrent的ownable synchronizers列表。
root@cv-console-rds-68784cdf9c-zk4d8:/# jstack -l 1
2022-05-06 11:13:21
Full thread dump OpenJDK 64-Bit Server VM (25.312-b07 mixed mode):
"clientOutboundChannel-65" #5189 prio=5 os_prio=0 tid=0x00007f9290006000 nid=0x1b64c waiting on condition [0x00007f92e98e7000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f6fc58b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
"clientOutboundChannel-64" #5188 prio=5 os_prio=0 tid=0x00007f9290005000 nid=0x1b64b waiting on condition [0x00007f92ea1ea000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f6fc58b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
"http-nio-31105-exec-18" #5074 daemon prio=5 os_prio=0 tid=0x00007f92c400f000 nid=0x1aae8 waiting on condition [0x00007f92e92e1000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f7e7e5d8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:89)
at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:33)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
-m参数
如果使用-m参数,jstack命令将显示混合的栈帧信息,除了Java方法栈帧以外,还有本地方法栈帧。本地方法栈帧是C或C++编写的虚拟机代码或JNI/native代码。
root@cv-console-rds-68784cdf9c-zk4d8:/# jstack -m 1 Attaching to process ID 1, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.312-b07 Deadlock Detection: No deadlocks found. ----------------- 6 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 7 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 8 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 9 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 10 ----------------- 0x00007f939b75b174 do_futex_wait.constprop.0 + 0x34 ----------------- 11 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 12 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 13 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 14 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 25 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 26 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 93 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 94 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 95 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 96 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 103 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 110 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 111 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 112 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 149 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 181 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 182 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 189 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 190 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 191 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 205 ----------------- 0x00007f939b465116 epoll_wait + 0x56 0x00007f938642aa32-F 参数----------------- 206 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 207 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 208 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 209 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 210 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 211 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 212 ----------------- 0x00007f939b465116 epoll_wait + 0x56 0x00007f938642aa32 ----------------- 213 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 216 ----------------- 0x00007f939b465116 epoll_wait + 0x56 0x00007f938642aa32 ----------------- 218 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 219 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 220 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 221 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 222 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 223 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 224 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 225 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 226 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 227 ----------------- 0x00007f939b465116 epoll_wait + 0x56 0x00007f938642aa32 ----------------- 228 ----------------- 0x00007f939b75c1bf __libc_accept + 0x4f 0x00007f9386dc2f6a ----------------- 235 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 646 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 16973 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 16974 ----------------- 0x00007f939b45a3ff __poll + 0x4f 0x00007f9384be2745 Java_java_net_SocketInputStream_socketRead0 + 0xe5 0x00007f938512eea1 ----------------- 16975 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 16976 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 17045 ----------------- 0x00007f939b7587b2 __pthread_cond_wait + 0x1e2 ----------------- 31525 ----------------- 0x00007f939b75c1bf __libc_accept + 0x4f 0x00007f939a66c0bc _ZN14AttachListener7dequeueEv + 0xac 0x00007f939a66afc0 _ZL28attach_listener_thread_entryP10JavaThreadP6Thread + 0x1a0 0x00007f939add8c11 _ZN10JavaThread17thread_main_innerEv + 0xf1 0x00007f939ac859d2 _ZL10java_startP6Thread + 0x132 ----------------- 101980 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 108911 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 108912 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 108913 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 108914 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 108915 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 108916 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 108935 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 109288 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 112203 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 112204 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 113392 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 113393 ----------------- 0x00007f939b758ad8 __pthread_cond_timedwait + 0x238 ----------------- 1 ----------------- 0x00007f939b7534a7 __pthread_clockjoin_ex + 0x237 0x00007f939a208700 ???????? 0x00007f939b53bf80 JLI_Launch + 0x9e0 0x000055e98320d836 main + 0x76
如果Java虚拟机进程由于进程挂起而没有任何响应,那么可以使用-F参数(仅在Oracle Solaris和Linux操作系统上游戏)强制显示线程快照信息。
root@cv-console-rds-68784cdf9c-zk4d8:/# jstack -F 1 Attaching to process ID 1, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.312-b07 Deadlock Detection: No deadlocks found. Thread 113636: (state = BLOCKED) - java.lang.Thread.sleep(long) @bci=0 (Compiled frame; information may be imprecise) - sun.net.www.http.KeepAliveCache.run() @bci=3, line=172 (Interpreted frame) - java.lang.Thread.run() @bci=11, line=748 (Compiled frame) Thread 113591: (state = BLOCKED) - sun.misc.Unsafe.park(boolean, long) @bci=0 (Compiled frame; information may be imprecise) - java.util.concurrent.locks.LockSupport.parkNanos(java.lang.Object, long) @bci=20, line=215 (Compiled frame) - java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(long) @bci=78, line=2078 (Compiled frame) - java.util.concurrent.LinkedBlockingQueue.poll(long, java.util.concurrent.TimeUnit) @bci=62, line=467 (Compiled frame) - java.util.concurrent.ThreadPoolExecutor.getTask() @bci=134, line=1073 (Compiled frame) - java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=26, line=1134 (Compiled frame) - java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=624 (Compiled frame) - java.lang.Thread.run() @bci=11, line=748 (Compiled frame) Thread 113590: (state = BLOCKED) - sun.misc.Unsafe.park(boolean, long) @bci=0 (Compiled frame; information may be imprecise) - java.util.concurrent.locks.LockSupport.parkNanos(java.lang.Object, long) @bci=20, line=215 (Compiled frame) - java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(long) @bci=78, line=2078 (Compiled frame) - java.util.concurrent.LinkedBlockingQueue.poll(long, java.util.concurrent.TimeUnit) @bci=62, line=467 (Compiled frame) - java.util.concurrent.ThreadPoolExecutor.getTask() @bci=134, line=1073 (Compiled frame) - java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=26, line=1134 (Compiled frame) - java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=624 (Compiled frame) - java.lang.Thread.run() @bci=11, line=748 (Compiled frame) Thread 112204: (state = BLOCKED) - sun.misc.Unsafe.park(boolean, long) @bci=0 (Compiled frame; information may be imprecise) - java.util.concurrent.locks.LockSupport.parkNanos(java.lang.Object, long) @bci=20, line=215 (Compiled frame) - java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(long) @bci=78, line=2078 (Compiled frame) - java.util.concurrent.LinkedBlockingQueue.poll(long, java.util.concurrent.TimeUnit) @bci=62, line=467 (Compiled frame) - java.util.concurrent.ThreadPoolExecutor.getTask() @bci=134, line=1073 (Compiled frame) - java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=26, line=1134 (Compiled frame) - java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=624 (Compiled frame) - java.lang.Thread.run() @bci=11, line=748 (Compiled frame)实践 -排查某个等待时间长的线程
# 匹配到xxxxxx内容+前5行+后5行 jstack -l 1 | grep -C 5 WAITING # 匹配到xxxxxx内容+前5行 jstack -l 1 | grep -B 5 WAITING # 匹配到xxxxxx内容+后5行 jstack -l 1 | grep -C 5 WAITING



