`

Thread Dump 和Java应用诊断

    博客分类:
  • JVM
阅读更多
Thread Dump 和Java应用诊断

 

Thread Dump是非常有用的诊断Java应用问题的工具,每一个Java虚拟机都有及时生成显示所有线程在某一点状态的thread-dump的能力。虽然 各个Java虚拟机thread dump打印输出格式上略微有一些不同,但是Thread dumps出来的信息包含线程;线程的运行状态、标识和调用的堆栈;调用的堆栈包含完整的类名,所执行的方法,如果可能的话还有源代码的行数。

Thread Dump特点:

  • 能在各种操作系统下使用
  • 能在各种Java应用服务器下使用
  • 可以在生产环境下使用而不影响系统的性能
  • 可以将问题直接定位到应用程序的代码行上

Thread Dump能诊断的问题包括:

  • 查找内存泄露,常见的是程序里load大量的数据到缓存
  • 发现死锁线程

Sun的JVM用下列方法可以产生Thread Dump堆栈信息:

1,Solaris OS
<ctrl>-’\’ (Control-Backslash)
 kill -QUIT <pid>

2, HP-UX/UNIX/Linux
Kill -3 PID 
PID通过下面方法获取
ps -efHl | grep 'java' **. **

3,Windows
直接对MSDOS窗口的程序按Ctrl-break

有些Java应用服务器是在控制台上运行,如Weblogic,为了方便获取threaddump信息,在weblogic启动的时候,最好将其标准输出重定向到一个文件,用"nohup sh startWebLogic.sh > start.log &"命令,执行"kill -3 <pid>",Stack trace就会输出到start.log里。Tomcat的Thread Dump会输出到命令行控制台或者logs的catalina.out文件里。为了 反映线程状态的动态变化,需要接连多次做thread dump,每次间隔10-20s。

IBM JVM下产生Thread Dump:

在AIX上用IBM的JVM,内存溢出时默认地会产生javacore文件(关于cpu的)和heapdump文件(关于内存的)。如果没有参照下列方法:
1 choose one cluster member, set the following before this server start:
在was启动前设置下面环境变量(可以加在启动脚本中)
export IBM_HEAPDUMP=true
export IBM_HEAP_DUMP=true
export IBM_HEAPDUMP_OUTOFMEMORY=true
export IBM_HEAPDUMPDIR=<directory path>

2 please use set command to make sure you do not have DISABLE_JAVADUMP parameter
then start this cluster member.
用set命令检查参数设置,确保没有设置DISABLE_JAVADUMP,然后启动server

3 when you find free memory < 50% when no heavy access, please run kill -3 <pid>
执行kill -3 <pid>命令可以生成javacore文件和heapdump文件(pid为was java进程的id号,可以用ps -ef|grep java 查到),可以多执行几次,按照下面操作进行

ps -ef > psef1.txt
ps aux > psaux1.txt
vmstat 5 10 > vmstat.txt
kill -3 <app server id>
wait for 2 mins
kill -3 <app server id>
wait for 2 mins
kill -3 <app server id>
netstat -an> netstat2.txt
ps -ef > psef2.txt
ps aux > psaux2.txt
将上面产生的 txt 文件和/usr/WebSphere/AppServer/javacore*文件和heapdump文件拷贝到本地,然后删除这些文件,因为这些文件会占用较大的文件系统空间。
将/usr/WebSphere/AppServer/logs/wlmserver1(或2)目录下当天产生的日志拷贝出来


在IBM JVM产生的javacore或者Threaddump文件中应用服务器Web容器的常见线程状态

Idle线程:一个已经准备好接受请求的线程,但是没有和插件或者客户端建立连接
Keep-Alive线程:是一个已经准备好接受请求的线程,并且已经和插件或者客户端建立连接
正在接受请求的线程:是一个线程正在读取request的内容或者头部

下面就给出各种线程在javacore或者Threaddump中的表现形式:

Idle线程:
"Servlet.Engine.Transports : 20" (TID:0x427F190, sys_thread_t:0x15D175E8, state:R, native ID:0xBB8) prio=5
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:429)
at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161)
at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java(Compiled Code)) at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java(Compiled Code))

Keep-alive线程 (非SSL模式):
"Servlet.Engine.Transports : 20" (TID:0x427F190, sys_thread_t:0x15D175E8, state:R, native ID:0xBB8) prio=5
at java.net.SocketInputStream.socketRead(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:86)
at com.ibm.ws.io.Stream.read(Stream.java)
at com.ibm.ws.io.ReadStream.readBuffer(ReadStream.java)
at com.ibm.ws.io.ReadStream.read(ReadStream.java)
at com.ibm.ws.http.HttpRequest.readRequestLine(HttpRequest.java)
at com.ibm.ws.http.HttpRequest.readRequest(HttpRequest.java)
at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java)
at com.ibm.ws.http.HttpConnection.run(HttpConnection.java)
at com.ibm.ws.util.CachedThread.run(ThreadPool.java)

Keep-alive线程 (SSL模式):
"Servlet.Engine.Transports : 12" (TID:0x458DBA18, sys_thread_t:0x60B297C0, state:R, native ID:0x427E) prio=5
at java.net.SocketInputStream.socketRead(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java(Compiled Code))
at com.ibm.sslite.s.a(Unknown Source)(Compiled Code)
at com.ibm.sslite.s.b(Unknown Source)(Compiled Code)
at com.ibm.sslite.s.a(Unknown Source)(Compiled Code)
at com.ibm.sslite.a.read(Unknown Source)(Compiled Code)
at com.ibm.jsse.a.read(Unknown Source)(Compiled Code)
at com.ibm.ws.io.Stream.read(Stream.java(Compiled Code))
at com.ibm.ws.io.ReadStream.readBuffer(ReadStream.java(Inlined Compiled Code))
at com.ibm.ws.io.ReadStream.read(ReadStream.java(Inlined Compiled Code))
at com.ibm.ws.http.HttpRequest.readRequestLine(HttpRequest.java(Compiled Code))
at com.ibm.ws.http.HttpRequest.readRequest(HttpRequest.java(Compiled Code))
at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection)
at com.ibm.ws.http.HttpConnection.run(HttpConnection.java(Compiled Code))
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:672)


正在接受请求的线程:
at java.net.SocketInputStream.socketRead(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:85)
at com.ibm.ws.io.Stream.read(Stream.java:17)
at com.ibm.ws.io.ReadStream.readBuffer(ReadStream.java:411)
at com.ibm.ws.io.ReadStream.read(ReadStream.java:110)
at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:448)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:672)


Sun JVM的常见线程状态

对于thread dump信息,主要关注的是线程的状态和其执行堆栈
线程的状态一般为三类
Runnable(R):当前可以运行的线程
Waiting on monitor(CW):线程主动wait
Waiting for monitor entry(MW):线程等锁
一般关注的都是第一和第三种状态的线程
Cpu很忙则关注runnable的线程
Cpu闲则关注waiting for monitor entry的线程
一种典型的死锁是由于在server端应用(比如servlet)中请求由同一weblogic实例server的资源
解决办法就是将该servlet放到另外的执行队列里去执行

下面给出一个典型的死锁线程(注意STUCK关键字 ):

"[STUCK ] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=10 tid=02fe9a18 nid=35 lwp_id=7518924 runnable [440dd000..440db878]
 at java.net.SocketInputStream.socketRead0(Native Method)
 at java.net.SocketInputStream.read(SocketInputStream.java:134)
 at weblogic.jdbc.oracle.net8.OracleDataProvider.getArrayOfBytesFromSocket(Unknown Source)
 at weblogic.jdbc.oracle.net8.OracleDataProvider.readFirstPacketInBuffer(Unknown Source)
 at weblogic.jdbc.oracle.net8.OracleDataProvider.readPacket(Unknown Source)
 at weblogic.jdbc.oracle.net8.OracleDataProvider.receive(Unknown Source)
 at weblogic.jdbc.oracle.net8.OracleNet8NSPTDAPacket.sendRequest(Unknown Source)
 at weblogic.jdbc.oracle.OracleImplStatement.fetchNext(Unknown Source)
 at weblogic.jdbc.oracle.OracleImplStatement.fetchNext2(Unknown Source)
 at weblogic.jdbc.oracle.OracleImplResultset.fetchAtPosition(Unknown Source)
 at weblogic.jdbc.base.BaseImplResultSet.next(Unknown Source)
 at weblogic.jdbc.base.BaseResultSet.next(Unknown Source)
 - locked <55f25550> (a weblogic.jdbc.oracle.OracleConnection)
 at weblogic.jdbc.wrapper.ResultSet_weblogic_jdbc_base_BaseResultSet.next(Unknown Source)
 at org.hibernate.loader.Loader.doQuery(Loader.java:685)

UNIX/Linux下可用top、vmstat或prstat 命令观察系统资源状况

分享到:
评论

相关推荐

    Java thread dump analyzer (tda)

    Java线程分析工具(TDA)是一款专为Java开发者设计的强大工具,用于解析和理解Java应用程序的线程转储(thread dump)。线程转储是Java虚拟机(JVM)在特定时刻生成的一种快照,其中包含了应用程序中所有活动线程的状态...

    IBM Thread and Monitor Dump Analyzer for Java

    IBM Thread and Monitor Dump Analyzer for Java 是一款专门针对...结合`jca395.jar`、`jca.properties.xml`、`readme.zip`和`license`这些文件,用户可以全面地了解和使用这款工具来诊断和修复Java应用程序的问题。

    java故障排查ThreadDump

    在Java开发及运维工作中,Thread Dump是一项极其重要的工具,它能够帮助我们诊断并解决Java应用程序中出现的各种问题。Thread Dump,即线程快照,是指Java虚拟机(JVM)在某一时间点捕捉到的所有线程的状态快照。通过...

    IBM thread dump文件分析工具

    IBM Thread and Monitor Dump Analyzer(TMDA,也称作jca)是一个专门用于解析和分析这些线程dump文件的工具,尤其对于IBM Java运行环境,它提供了强大的诊断能力。 首先,线程状态是理解线程dump文件的关键。Java...

    用Java thread dump 去分析程序的问题

    Java线程转储(Thread Dump)是诊断Java应用程序性能问题和异常情况的重要工具。它提供了一个运行中的Java应用中所有线程的快照,详细显示每个线程的状态、堆栈跟踪以及线程名称。线程状态包括RUNNABLE、BLOCKED、...

    tda看ThreadDump文件

    - **组合使用jstack和tda**:在遇到Java应用性能问题或者线程异常时,先用`jstack`生成Thread Dump,然后使用tda进行解析和分析,这样可以提高问题定位的效率和准确性。 - **线程分析**:tda可以识别出可能的死锁...

    Thread Dump Analyzer - tda-bin-2.3.3

    总的来说,Thread Dump Analyzer(TDA)是Java开发者诊断和优化多线程应用的重要工具,它简化了对线程转储日志的理解和处理过程,提升了问题排查的效率。使用TDA 2.3.3版本,开发者能够更高效地定位和解决与线程相关...

    Thread Dump Analyzer

    线程转储是在特定时间点应用程序中所有线程的状态快照,它包含了每个线程的详细信息,如线程ID、线程状态、堆栈跟踪等,这对于诊断和解决多线程编程中的性能问题和死锁状况至关重要。 当Java应用程序遇到性能瓶颈或...

    TDA - Thread Dump Analyzer 2.3.2

    为了有效地诊断和解决这些问题,开发者通常需要借助线程转储(Thread Dump)分析工具。其中,TDA(Thread Dump Analyzer)2.3.2是一款强大的开源工具,专为Java开发人员提供高效、精准的线程分析服务。它的出现,...

    JAVA线程dump的分析

    本文中,我们使用SUN的hotspot JVM 5.0_06为例,展示了如何生成和分析JAVA线程dump,帮助开发者诊断和优化JAVA程序。 在JAVA程序中,线程分析是非常重要的,了解当前程序的执行情况,能够帮助开发者诊断问题和性能...

    Thread Dump Analyzer - tda-bin-2.2.zip

    Thread Dump Analyzer(TDA)是一款强大的工具,专为Java开发者设计,用于解析和分析Java应用程序的线程转储(Thread Dump)。线程转储是Java虚拟机(JVM)在特定时间点对所有运行线程状态的快照,通常用于诊断多...

    IBM Thread and Monitor Dump Analyzer (TMDA)

    在Java应用开发和运维过程中,线程 dump 是诊断和解决性能问题、死锁、线程阻塞等关键问题的重要手段。TMDA 提供了丰富的功能,帮助开发者和系统管理员深入理解应用程序的线程状态,从而优化系统性能。 1. **线程...

    sun threaddump analyzer

    Sun Thread Dump Analyzer(简称TDA)是一款专门用于分析Java虚拟机(JVM)中的线程转储快照(Thread Dump)的工具。线程转储是JVM在特定时刻生成的一种快照,它包含了所有运行中线程的状态信息,这对于诊断Java应用...

    IBM Thread and Monitor Dump Analyzer for Java jca37

    了解和熟练运用这款工具,将有助于我们更有效地诊断和优化Java应用,提升系统的稳定性和效率。 内存溢出(OutOfMemoryError)是Java编程中常见的错误,通常由于程序分配的内存超过了JVM(Java虚拟机)可以管理的...

    javacore\heapdump文件分析工具

    同时,开发者还需要了解Websphere的配置和应用代码,以便更准确地定位问题。 总结来说,`javacore`和`heapdump`分析是Java性能优化的关键环节,`ha`和`jca`工具为开发者提供了强大的诊断能力。正确理解和使用这些...

    Java Thread Dumps 分析

    总之,深入理解和熟练运用Java线程转储分析是每一个Java开发者必备的技能,它可以帮助你有效地诊断和解决应用程序中的各种并发问题,提高系统的稳定性和性能。通过阅读这两份文档,你可以系统地学习这个主题,并将所...

Global site tag (gtag.js) - Google Analytics