`

Thread Dump 和Java应用诊断

阅读更多

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命令观察系统资源状况


 Mandy Chung's Blog 有一篇关于Thread Dump and Concurrency Locks的blog,摘来如下:

Thread dumps are very useful for diagnosing synchronization related problems such as deadlocks on object monitors. Ctrl-\ on Solaris/Linux or Ctrl-Break on Windows has been a common way to get a thread dump of a running application. On Solaris or Linux, you can send a QUIT signal to the target application. The target application in both cases prints a thread dump to the standard output and also detects if there is any deadlock involving object monitors.

jstack, a new troubleshooting utility introduced in Tiger (J2SE 5.0), provides another way to obtain a thread dump of an application. Alan Bateman has a nice blog about jstack and its several improvements in Mustang (Java SE 6). Mustang jstack works like a remote Ctrl-\ or Ctrl-Break if you are on Windows.

jconsole is JMX-complaint GUI tool which allows you to get a thread dump on the fly. The "Using JConsole to Monitor Applications" article gives you an overview of the Tiger monitoring and management functionality.

Mustang extends the thread dump, jstack, and jconsole to support java.util.concurrent.locks to improve its diagnosability. For example, the Threads tab in the Mustang jconsole now shows which synchronizer a thread is waiting to acquire when the thread is blocked to lock a ReentrantLock and also which thread is owning that lock.

 

In addition, it has a new "detect deadlock" button (in the bottom). When you click on the "detect deadlock" button, it will send a request to the target application to perform the deadlock detection operation. If the target application is running on Mustang, it finds deadlocks involving both object monitors as well as the java.util.concurrent.locks. If the target application is running on Tiger, it finds deadlocks involving object monitors only. Each deadlock cycle will be displayed in a separate Deadlock tab.

 

Click here to see a wider form of this screenshot.

JDK 6 has a nice demo FullThreadDump under $JDK_HOME/demo/management/FullThreadDump where JDK_HOME is the location of your JDK 6. This demo has been included in JDK 5.0 and is updated to use the new Mustang API. It demonstrates the use of the java.lang.management API to get the thread dump and detect deadlock programmatically.

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wonder4/archive/2007/05/23/1623250.aspx

分享到:
评论

相关推荐

    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