`
五月天
  • 浏览: 21598 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

深入理解jstack日志

 
阅读更多

在分析线上问题时常使用到jstack <PID>命令将当时Java应用程序的线程堆栈dump出来。
面对jstack 日志,我们如何查看?

 

首先要清楚线程的状态
线程的状态有:new、runnable、running、waiting、timed_waiting、blocked、dead
线程状态变迁图:

 

 

各状态说明:
New: 当线程对象创建时存在的状态,此时线程不可能执行;
Runnable:当调用thread.start()后,线程变成为Runnable状态。只要得到CPU,就可以执行;
Running:线程正在执行;
Waiting:执行thread.join()或在锁对象调用obj.wait()等情况就会进该状态,表明线程正处于等待某个资源或条件发生来唤醒自己;
Timed_Waiting:执行Thread.sleep(long)、thread.join(long)或obj.wait(long)等就会进该状态,与Waiting的区别在于Timed_Waiting的等待有时间限制;
Blocked:如果进入同步方法或同步代码块,没有获取到锁,则会进入该状态;
Dead:线程执行完毕,或者抛出了未捕获的异常之后,会进入dead状态,表示该线程结束

 

其次,对于jstack日志,我们要着重关注如下关键信息
Deadlock:表示有死锁
Waiting on condition:等待某个资源或条件发生来唤醒自己。具体需要结合jstacktrace来分析,比如线程正在sleep,网络读写繁忙而等待
Blocked:阻塞 Waiting on monitor entry:在等待获取锁
in Object.wait():获取锁后又执行obj.wait()放弃锁 
对于Waiting on monitor entry  in Object.wait()的详细描述:Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。从下图中可以看出,每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 "Active Thread",而其它线程都是 "Waiting Thread",分别在两个队列 " Entry Set"和 "Wait Set"里面等候。在 "Entry Set"中等待的线程状态是 "Waiting for monitor entry",而在 "Wait Set"中等待的线程状态是 "in Object.wait()"

 

 

最后通过示例来实践一下
示例一:描述 Blocked 和 Waiting to lock 

 

执行后程序输出:
Thread[main,5,main]
说明主线程先进入同步代码块,获取到thread2对象上的锁。
通过jstack输出结果:

先说明下日志格式:
"thread2"为线程名称,在平时创建线程或线程池时请务必取一个见明之义的线程名称,方便排查问题
prio=6:线程优先级,不用关心;
tid=0x0000000006540800:线程id,不用关心;
nid=0x2be4:操作系统映射的线程id, 非常关键,后面再使用jstack时补充
waiting for monitor entry:表示线程正在等待获取锁
0x0000000006dbf000:线程栈起始地址

 

从jstack日志中,可以看到:主线程获取到thread2对象上的锁,因此正在执行sleep操作,状态为TIMED_WAINTING, 而thread2由于未获取到thread2对象上的锁,因此处于BLOCKED状态。
再细看,thread2 正在"waiting to lock <0x00000000d719d280>",即试图在地址为0x00000000d719d280所在的对象获取锁,而该锁却被main线程占有(locked <0x00000000d719d280>)。main线程正在"waiting on condition",说明正在等待某个条件触发,由jstacktrace来看,此线程正在sleep。
经验:如果在jstack日志发现大量的线程在waiting to lock 某个地址,只要能查到哪个线程获取到锁就可以方便定位问题了

 

示例二:描述waiting on condition

]

jstack日志输出结果:

从日志中可以看到,main线程的状态是Waiting,正在"waiting on condition"来唤醒自己。
结合jstackstrace日志来看,"parking to wait for <0x00000000d719ba70> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)"说明在调用ArrayBlockingQueue.put()阻塞了。

 

示例三:描述Object.wait()

程序输出结果:
Thread[thread2,5,main]
Thread[main,5,main]
说明线程thread2先进入同步代码块,获取到thread2对象上的锁。
jstack日志输出结果:

 

可以看出:线程thread2的状态是"Waiting", 正在"in Object.wait()"。表明该线程在获取到对象锁后,调用obj.wait()方法,放弃了锁,进入了"Wait Set"队列。

 

  • 大小: 48.1 KB
  • 大小: 13.5 KB
  • 大小: 38.8 KB
  • 大小: 27.3 KB
  • 大小: 28.3 KB
  • 大小: 21.5 KB
  • 大小: 16 KB
  • 大小: 18.3 KB
  • 大小: 46.1 KB
分享到:
评论

相关推荐

    Java线程Dump分析工具jstack解析及使用场景

    本文将深入解析jstack的使用方法及其在不同场景下的应用。 jstack命令的基本格式如下: ``` jstack [-l] [-F] pid ``` 其中,`pid` 是Java进程的ID,`-l` 选项会提供更详细的线程和锁信息,而 `-F` 选项则用于在...

    jstack生成的Thread Dump日志.docx

    《深入解析JVM线程Dump日志:剖析线程状态与优化策略》 线程状态是理解Java应用程序性能的关键因素之一。JVM提供了一个强大的工具——`jstack`,用于生成线程堆栈转储,即Thread Dump,帮助开发者洞察线程的运行...

    MPP的jstack分析结果

    《深入理解MPP系统中的jstack分析》 在IT领域,特别是大数据处理中,MPP(Massive Parallel Processing)系统因其高效的数据处理能力而被广泛应用。然而,随着系统的复杂性增加,性能调优和问题排查变得至关重要。...

    jstack生成的Thread Dump日志1

    【标题】:深入解析jstack生成的Thread Dump日志 【描述】:jstack命令用于生成Java应用程序的线程堆栈跟踪,它可以帮助开发者诊断Java应用中的线程问题。线程Dump日志提供了详细的线程状态和调用栈信息,这对于...

    jstack-jboss-7.5.0-Final.zip

    总结来说,这个场景涉及了Java多线程编程中的死锁问题,通过`jstack`工具分析`8508.jstack2.log`文件可以找出可能的死锁链,并结合`logging.properties`文件了解日志配置,进一步深入代码分析以解决问题。...

    JStack:JStack - 一个开源的判断系统

    这可能涉及到数据库连接、评分规则、日志记录等多个方面,同时也可能涉及如何集成JStack来进行线程分析,以确保代码运行的稳定性和效率。 总之,JStack是一个强大的诊断工具,用于检查Java应用程序的线程状态,而...

    JVM crash 错误日志分析

    通过对这个日志的深入分析,我们可以找出问题的原因并采取相应的解决措施。 首先,我们需要了解JVM崩溃的常见原因。这可能包括内存溢出(Out of Memory Error)、线程死锁、非法指令、系统资源耗尽等。错误日志通常...

    深入理解java虚拟机的故障处理工具

    `jstack`会列出每个线程的堆栈轨迹,帮助开发者理解线程当前的执行状态。 了解并熟练使用这些工具,开发者可以更有效地诊断和解决问题,提升Java应用的性能和稳定性。在实际工作中,结合日志、性能指标以及这些故障...

    查看WebSphere的javacore日志工具

    通过使用"Thread"这样的工具,我们可以深入理解JVM内部的工作原理,有效提升系统的稳定性和性能。在实际操作中,结合WebSphere的其他监控工具和日志,如SystemOut.log、HeapDump、ThreadDump等,可以更全面地诊断和...

    imb jca436

    在IBM的JCA436中,可能包含了针对IBM特定JVM实现的Jstack增强功能,例如更详细的JCA连接器相关日志、性能指标或特定问题的解决方案。使用这个工具,开发者和运维人员能够更有效地诊断和解决IBM Java环境中遇到的JCA...

    Java线程检测和数据收集工具

    本文将深入探讨如何使用Java提供的工具——`jps`和`jstack`,以及如何通过Shell脚本来定时收集Java进程的线程信息。 首先,`jps`(JVM Process Status)是Java虚拟机进程状况工具,它能够列出正在运行的Java进程ID...

    深入剖析TOMCAT+Tomcat权威指南(第二版)

    学会阅读和解析Tomcat的日志,结合JVM的监控工具(如jstack、jmap等),可以定位和解决问题。 九、Tomcat与Spring Boot整合 Spring Boot简化了Java应用的开发和部署,而Tomcat是其默认的嵌入式服务器。了解如何在...

    深入java虚拟机第二版

    2. **内存管理**:涵盖堆内存、栈内存、方法区、本地方法栈等,特别关注垃圾收集机制,如分代收集、可达性分析算法以及GC日志分析。 3. **字节码指令集**:理解JVM执行的二进制指令,包括各种操作码的意义和作用,...

    教你找出 运行java项目,使cpu 100%,如何排查出是哪个jar包的哪个线程导致的

    在Java开发过程中,有时会遇到项目运行时CPU占用率达到100%的问题,这可能是由于某个线程...通过深入理解这些工具和方法,你可以有效地预防和解决Java项目运行时CPU使用率过高的问题,从而确保应用程序的稳定性和效率。

    Java线上故障排查方案.rar

    1. 日志级别:理解DEBUG、INFO、WARN、ERROR等不同级别的含义,根据情况调整日志级别以获取所需信息。 2. 异常堆栈:通过查看错误堆栈跟踪,可以定位到问题发生的具体代码行。 3. 日志切割:定期或按大小切割日志,...

    Java问题定位技术的文档

    总的来说,Java问题定位技术涵盖了日志分析、堆栈跟踪、性能监控、调试工具的使用、代码质量保证以及深入理解JVM等多个方面。熟练掌握这些技术,将使我们面对问题时更加从容,提高问题解决的效率。

    Java工程师成神之路~-HollisChuang's Blog1

    Java的基础知识同样重要,包括深入理解String、Integer等核心类的源码,熟悉各种变量类型、关键字以及数据结构的使用。例如,String的不可变性、StringBuilder和StringBuffer的区别,以及如何有效地实现List的排序和...

    TongWeb启动慢.doc

    一旦发现有特定的操作执行时间过长,比如数据库驱动的初始化,就可以通过`jstack`命令获取Java进程的线程堆栈信息,从而深入分析问题。 例如,日志显示数据库驱动在执行`getLocalHost`操作时耗时较长。`...

    实战JAVA虚拟机随书源码

    通过分析和实践这些源码,我们可以深入理解JVM的工作原理,提升我们的Java应用开发和调优能力。本文将详细探讨相关知识点。 一、JVM故障诊断 1. 堆内存溢出:源码中可能包含模拟堆内存溢出的场景,帮助我们理解如何...

    jvm调试示例代码

    在Java开发过程中,JVM(Java虚拟机)的调试是一项重要的技能,它能帮助开发者深入理解程序运行时的内部机制,解决性能问题和错误。本示例代码集合旨在提供一个实践平台,帮助开发者掌握JVM调试技巧。我们将探讨以下...

Global site tag (gtag.js) - Google Analytics