[Java故障排除指南- JDK11-学习笔记]-5-线程堆栈与死锁问题检测

5-线程堆栈与死锁问题检测

线程堆栈分析

在程序运行时我们想要查看程序的执行状态,可以通过进程的线程堆栈信息来分析进程的健康状态,如果获取到一个运行中的Java进程的线程堆栈呢,我们可以用这几个命令:

先查询Java进程id

jps -l 

通过Java进程id查询当前进程的堆栈信息

 jstack -l 17389

如下是实际操作中的一个案例


➜  ~ jps -l
288 org.jetbrains.jps.cmdline.Launcher
66245
1670 sun.tools.jps.Jps
17389 org.apache.zookeeper.server.quorum.QuorumPeerMain
➜  ~ jstack -l 17389
2022-05-10 21:12:05
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode):

"VM JFR Buffer Thread" #23 daemon prio=5 os_prio=31 tid=0x00007fefed04a000 nid=0x6003 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"JFR request timer" #21 daemon prio=5 os_prio=31 tid=0x00007fefec2ad800 nid=0x5f03 in Object.wait() [0x000070000fdee000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at java.util.TimerThread.mainLoop(Timer.java:526)
	- locked <0x00000006c0027df8> (a java.util.TaskQueue)
	at java.util.TimerThread.run(Timer.java:505)

   Locked ownable synchronizers:
	- None

"RMI Scheduler(0)" #18 daemon prio=5 os_prio=31 tid=0x00007fefec07b800 nid=0x5d03 waiting on condition [0x000070000fae5000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000006c0016c50> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
	at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
	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

"Attach Listener" #16 daemon prio=9 os_prio=31 tid=0x00007fefec066800 nid=0x4827 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"ProcessThread(sid:0 cport:2181):" #15 prio=5 os_prio=31 tid=0x00007fefec156800 nid=0x5b03 waiting on condition [0x000070000f7dc000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000006c0035808> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
	at org.apache.zookeeper.server.PrepRequestProcessor.run(PrepRequestProcessor.java:123)

   Locked ownable synchronizers:
	- None

"SyncThread:0" #14 prio=5 os_prio=31 tid=0x00007fefec90a800 nid=0xa103 waiting on condition [0x000070000f6d9000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000006c002ff98> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
	at org.apache.zookeeper.server.SyncRequestProcessor.run(SyncRequestProcessor.java:127)

   Locked ownable synchronizers:
	- None

"SessionTracker" #13 prio=5 os_prio=31 tid=0x00007fefec152000 nid=0xa303 in Object.wait() [0x000070000f5d6000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	at org.apache.zookeeper.server.SessionTrackerImpl.run(SessionTrackerImpl.java:147)
	- locked <0x00000006c00390d0> (a org.apache.zookeeper.server.SessionTrackerImpl)

   Locked ownable synchronizers:
	- None

"NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181" #12 daemon prio=5 os_prio=31 tid=0x00007fefeb09e000 nid=0xa403 runnable [0x000070000f4d3000]
   java.lang.Thread.State: RUNNABLE
	at sun.nio.ch.KQueueArrayWrapper.kevent0(Native Method)
	at sun.nio.ch.KQueueArrayWrapper.poll(KQueueArrayWrapper.java:198)
	at sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:117)
	at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
	- locked <0x00000006c00412c0> (a sun.nio.ch.Util$3)
	- locked <0x00000006c0041260> (a java.util.Collections$UnmodifiableSet)
	- locked <0x00000006c0041270> (a sun.nio.ch.KQueueSelectorImpl)
	at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
	at org.apache.zookeeper.server.NIOServerCnxnFactory.run(NIOServerCnxnFactory.java:203)
	at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
	- None

"RMI TCP Accept-0" #11 daemon prio=5 os_prio=31 tid=0x00007fefec8f0000 nid=0xa703 runnable [0x000070000f2cd000]
   java.lang.Thread.State: RUNNABLE
	at java.net.PlainSocketImpl.socketAccept(Native Method)
	at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
	at java.net.ServerSocket.implAccept(ServerSocket.java:545)
	at java.net.ServerSocket.accept(ServerSocket.java:513)
	at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:405)
	at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:377)
	at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
	- None

"Service Thread" #9 daemon prio=9 os_prio=31 tid=0x00007fefec83c800 nid=0xa803 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"C1 CompilerThread3" #8 daemon prio=9 os_prio=31 tid=0x00007fefec829000 nid=0x5603 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"C2 CompilerThread2" #7 daemon prio=9 os_prio=31 tid=0x00007fefec828000 nid=0x3e03 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"C2 CompilerThread1" #6 daemon prio=9 os_prio=31 tid=0x00007fefec827800 nid=0x3c03 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"C2 CompilerThread0" #5 daemon prio=9 os_prio=31 tid=0x00007fefec826000 nid=0x3a03 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

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

   Locked ownable synchronizers:
	- None

"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fefed01b000 nid=0x3203 in Object.wait() [0x000070000eab2000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
	- locked <0x00000006c0030a68> (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)

   Locked ownable synchronizers:
	- None

"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007fefed01a800 nid=0x3103 in Object.wait() [0x000070000e9af000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
	- locked <0x00000006c00359e8> (a java.lang.ref.Reference$Lock)
	at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

   Locked ownable synchronizers:
	- None

"main" #1 prio=5 os_prio=31 tid=0x00007fefed00a800 nid=0xe03 waiting on condition [0x000070000dd8b000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000006c0027e10> (a java.util.concurrent.CountDownLatch$Sync)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
	at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
	at org.apache.zookeeper.server.ZooKeeperServerMain.runFromConfig(ZooKeeperServerMain.java:125)
	at org.apache.zookeeper.server.ZooKeeperServerMain.initializeAndRun(ZooKeeperServerMain.java:89)
	at org.apache.zookeeper.server.ZooKeeperServerMain.main(ZooKeeperServerMain.java:55)
	at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(QuorumPeerMain.java:119)
	at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:81)

   Locked ownable synchronizers:
	- None

"VM Thread" os_prio=31 tid=0x00007fefeb013000 nid=0x3003 runnable

"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fefeb00e000 nid=0x1f07 runnable

"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fefeb00e800 nid=0x1a03 runnable

"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007fefeb00f800 nid=0x1c03 runnable

"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007fefeb010000 nid=0x2a03 runnable

"GC task thread#4 (ParallelGC)" os_prio=31 tid=0x00007fefeb010800 nid=0x5303 runnable

"GC task thread#5 (ParallelGC)" os_prio=31 tid=0x00007fefeb011000 nid=0x5203 runnable

"GC task thread#6 (ParallelGC)" os_prio=31 tid=0x00007fefeb012000 nid=0x2c03 runnable

"GC task thread#7 (ParallelGC)" os_prio=31 tid=0x00007fefec810800 nid=0x5003 runnable

"GC task thread#8 (ParallelGC)" os_prio=31 tid=0x00007fefec811000 nid=0x4f03 runnable

"GC task thread#9 (ParallelGC)" os_prio=31 tid=0x00007fefea808800 nid=0x4e03 runnable

"VM Periodic Task Thread" os_prio=31 tid=0x00007fefec0f0800 nid=0xa603 waiting on condition

JNI global references: 240

输出由许多由空行分隔的线程条目组成。Java 线程(能够执行 Java 语言代码的线程)首先打印,然后是有关 VM 内部线程的信息。每个线程条目都包含一个标题行,后跟线程堆栈跟踪。

下面这个做为参考 我们来看下每个字段的含义:

"main" #1 prio=5 os_prio=31 tid=0x00007fefed00a800 nid=0xe03 waiting on condition [0x000070000dd8b000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000006c0027e10> (a 

标题行包含有关线程的以下信息:

  • 线程名称,如: main。

  • 指示线程是否为守护线程 有daemon标记的则为守护线程。

  • 线程优先级(prio),如上面的5 。

  • 线程ID(tid),即线程结构在内存中的地址, 如tid=0x00007fefed00a800。

  • 本机线程的 ID (nid) 如 nid=0xe03 (我们是可以通过Linux进程分析命令top -Hp 来找到这个进程id的十进制,将其转为十六进制后就与这个nid对应了)。

  • 线程状态,指示线程在线程转储时正在做什么。有关详细信息,请参见下面表格。

  • 地址范围,它给出了线程有效堆栈区域的估计值。

线程转储的线程状态:

Thread StateDescription
NEWThe thread has not yet started. 线程还没有开始
RUNNABLEThe thread is executing in the JVM. 该线程正在 JVM 中执行。
BLOCKEDThe thread is blocked, waiting for a monitor lock. 线程被阻塞,等待监视器锁。
WAITINGThe thread is waiting indefinitely for another thread to perform a particular action. 线程无限期地等待另一个线程执行特定操作。
TIMED_WAITINGThe thread is waiting for another thread to perform an action for up to a specified waiting time. 该线程正在等待另一个线程执行操作,最长等待时间为指定的等待时间。
TERMINATEDThe thread has exited. 线程已退出。

检测死锁

如下是出现死锁的 信息描述

Found one Java-level deadlock:
=============================
"Thread2":
  waiting to lock monitor 0x000af330 (object 0xf819a938, a java.lang.String),
  which is held by "Thread1"
"Thread1":
  waiting to lock monitor 0x000af398 (object 0xf819a970, a java.lang.String),
  which is held by "Thread2"

Java stack information for the threads listed above:
===================================================
"Thread2":
        at Deadlock$DeadlockMakerThread.run(Deadlock.java:32)
        - waiting to lock <0xf819a938> (a java.lang.String)
        - locked <0xf819a970> (a java.lang.String)
"Thread1":
        at Deadlock$DeadlockMakerThread.run(Deadlock.java:32)
        - waiting to lock <0xf819a970> (a java.lang.String)
        - locked <0xf819a938> (a java.lang.String)

Found 1 deadlock.

Java HotSpot VM 中的探针提供程序
Java HotSpot VM 包含两个内置的探针提供程序hotspot和hotspot_jni.

这些提供程序提供的探针可用于监视 VM 的内部状态和活动,以及正在运行的 Java 应用程序。

JVM 探针提供程序可以分类如下:

  • VM 生命周期:VM 初始化开始和结束,以及 VM 关闭

  • 线程生命周期:线程启动和停止、线程名称、线程ID等

  • 类加载:Java类加载和卸载

  • 垃圾收集:系统范围或内存池的垃圾收集的开始和停止

  • 方法编译:方法编译开始和结束,方法加载和卸载

  • 监视器探测:等待事件、通知事件、竞争监视器进入和退出

  • 应用程序跟踪:方法进入和返回、Java 对象的分配

技术咨询支持,可以扫描微信公众号进行回复咨询
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宋小生的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值