Java常见命令之jstack

本文介绍如何使用jstack工具分析Java应用中的线程状态和堆栈信息,特别是如何诊断和解决线程死锁问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作用:查看Java线程的调用堆栈,生成Java虚拟机当前时刻的线程快照(Java虚拟机内每一条线程正在执行的方法堆栈集合),用来分析线程问题。

用法:jstack <options> [<pid>] [<executable> <core>] [server_id@]<remote server IP or hostname>

选项:

-F:强制dump线程栈信息

-l:长列表,打印关于锁的附加信息。当-l选项是出现提示如下图信息的时候,需要使用-F参数强制dump线程堆栈信息

-m:打印Java和native框架的所有栈信息

先熟悉一下线程的状态

NEW:未启动的。不会出现在Dump中

RUNNABLE:运行状态,对应RUNNABLE

BLOCKED:阻塞并等待监视器锁状态,此时在进入区等待

WATING:无限期等待另一个线程执行特定操作,对应输出的in Object.wait()

TIMED_WATING:有时限的等待另一个线程的特定操作对应输出的in Object.wait()

TERMINATED:已退出的状态

SLEEPING:线程休眠,调用了Thread.sleep()

下面通过编写的一个程序来分析jstack命令的使用以及输出解释,使用-l打印Java和native信息

死锁分析:

Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode):

"DestroyJavaVM" #15 prio=5 os_prio=0 tid=0x00000000023f9800 nid=0x1128 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None
//DeadLock-02线程想要执行第41行的时候阻塞,当前锁资源0x00000000d6211bd8,等待资源0x00000000d6211bc8
"DeadLock-02" #14 prio=5 os_prio=0 tid=0x0000000058caa000 nid=0x1d54 waiting for monitor entry [0x0000000059e4f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at learn.demo.JStackDemo$DeadLock.run(JStackDemo.java:41)
        - waiting to lock <0x00000000d6211bc8> (a java.lang.Object)
        - locked <0x00000000d6211bd8> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None
//DeadLock-01线程想要执行第32行的时候阻塞,当前锁资源0x00000000d6211bc8,等待资源0x00000000d6211bd8
"DeadLock-01" #13 prio=5 os_prio=0 tid=0x0000000058c8d000 nid=0x1dac waiting for monitor entry [0x000000005931f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at learn.demo.JStackDemo$DeadLock.run(JStackDemo.java:32)
        - waiting to lock <0x00000000d6211bd8> (a java.lang.Object)
        - locked <0x00000000d6211bc8> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:745)

   Locked ownable synchronizers:
        - None

"Service Thread" #12 daemon prio=9 os_prio=0 tid=0x0000000058afc000 nid=0x2648 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C1 CompilerThread2" #11 daemon prio=9 os_prio=2 tid=0x0000000058ae5000 nid=0x1900 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C2 CompilerThread1" #10 daemon prio=9 os_prio=2 tid=0x0000000058ae0800 nid=0x1294 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C2 CompilerThread0" #9 daemon prio=9 os_prio=2 tid=0x0000000058ada000 nid=0x2248 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"JDWP Command Reader" #8 daemon prio=10 os_prio=0 tid=0x00000000589e4800 nid=0x2b10 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"JDWP Event Helper Thread" #7 daemon prio=10 os_prio=0 tid=0x00000000589e1000 nid=0xd70 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"JDWP Transport Listener: dt_socket" #6 daemon prio=10 os_prio=0 tid=0x00000000589d2800 nid=0x26d8 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000057502000 nid=0xce8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000005750f800 nid=0xdb8 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

//Finalizer守护线程锁在资源0x00000000d5d08ec8,等待资源0x00000000d5d08ec8。
//为什么同时锁住的等待同一个资源?
//线程的执行中,先获得了这个对象的 Monitor(对应于 locked <0x00000000d5d08ec8>)。
//当执行到 obj.wait(), 线程即放弃了 Monitor的所有权,进入 “wait set”队列(对应于 waiting on <0x00000000d5d08ec8> )
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x00000000574eb000 nid=0x2684 in Object.wait() [0x00000000589ae000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d5d08ec8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x00000000d5d08ec8> (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=0x00000000574a3800 nid=0x27b4 in Object.wait() [0x000000005887e000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d5d06b68> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
        - locked <0x00000000d5d06b68> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

   Locked ownable synchronizers:
        - None

"VM Thread" os_prio=2 tid=0x000000005749c000 nid=0xb5c runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x000000000240e000 nid=0x17f0 runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x000000000240f800 nid=0x296c runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002411000 nid=0x2548 runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002414800 nid=0x29e4 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x0000000058c0b000 nid=0x21ac waiting on condition

JNI global references: 1655


//DeadLock-01在想要执行第32行的时候,当前锁住了资源<0x00000000d6211bc8>,但是他在等待资源<0x00000000d6211bd8>
//DeadLock-02在想要执行第27行的时候,当前锁住了资源<0x00000000d6211bd8>,但是他在等待资源<0x00000000d6211bc8>
//由于这两个线程都持有资源,并且都需要对方的资源,所以造成了死锁。 然后通过改写代码解决这个死锁
Found one Java-level deadlock:
=============================
"DeadLock-02":
  waiting to lock monitor 0x00000000574a7cb8 (object 0x00000000d6211bc8, a java.lang.Object),
  which is held by "DeadLock-01"
"DeadLock-01":
  waiting to lock monitor 0x00000000574aa6a8 (object 0x00000000d6211bd8, a java.lang.Object),
  which is held by "DeadLock-02"

Java stack information for the threads listed above:
===================================================
"DeadLock-02":
        at learn.demo.JStackDemo$DeadLock.run(JStackDemo.java:41)
        - waiting to lock <0x00000000d6211bc8> (a java.lang.Object)
        - locked <0x00000000d6211bd8> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:745)
"DeadLock-01":
        at learn.demo.JStackDemo$DeadLock.run(JStackDemo.java:32)
        - waiting to lock <0x00000000d6211bd8> (a java.lang.Object)
        - locked <0x00000000d6211bc8> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

关于多线程

多线程的讲解这里先不介绍,否则篇幅太长。可以看一下《并发编程的艺术》或自行学习

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值