如何使用 thread dump?如何分析Thread dump?

使用 thread dump

将会介绍三种常用的方法。请注意还会有其他很多方法可以获取Thread Dump。一个Thread dump仅仅可以显示测量时的线程状态。所以为了查看线程状态的变化,建议5到10次,每次间隔5秒。

kill -3 生成的dump文件默认不是独立的文件,而jstack命令则是生成的独立文件。

Solaris OS 下,使用kill -QUIT。---这个待实验。

linux/unix

linux下执行Kill -3 PID可以生成jvm的thread dump

  1. $ ps - ef | grep java 获得当前正在运行的java进程pid

  2. kill -3

注意生成的dump信息位置,如果nohup启动则会在nohup日志中,如果是按sh start.sh这种形式,则默认在日志文件中(tomcat的为catalina.out)

必要性:比如openJDK无法使用jstack命令时,就可以使用kill -3的方式来dump。

使用Java命令jstack获得Thread dump

1)获取java进程pid,获取方式如jps -v命令,ps -ef|grep java命令,top命令等等。。

2)jstack -f

jstack命令有几项参数,根据实际需要获取。

dump的信息为独立的文件。

使用jvisualvm工具获得Thread dump****

Jvisualvm工具连接指定Java,使用工具生成。

[图片上传失败...(image-b140d3-1663587485587)]

左边的标记,当前正在运行的进程。点击想查看的进程,选择现场选项来查看实时的线程信息。点击Thread dump右边的按钮来获得Thread dump文件

windows

在Windows下可以在JVM的console窗口上敲Ctrl-Break。根据不同的设置,thread dump会输出到当前控制台上或应用服务器的日志里。

如果想将日志输出到文件,可以修改tomcat/bin目录下的“catalina.bat”,在文件最后的四个ACTION后增加“>>%CATALINA_BASE%/logs/thread_demp.out”,同时修改bin目录下的startup.bat为:

rem call "%EXECUTABLE%" start "%CMD_LINE_ARGS%"
call "%EXECUTABLE%" run "%CMD_LINE_ARGS%"

这样就可以将日志输出到logs下的thread_dump.out文件中。也可以下载相应的分析工具对其进行分析。需要说明的一点是,将startup.bat修改为以上内容后,关闭tomcat时,直接关闭DOS窗口就可以了,不用shutdown.bat。

分析Thread dump

逆向分析:线程堆栈里面的最直观的信息是当前线程的调用上下文,即从哪个函数调用到哪个函数(从下往上看),正执行到哪一类的哪一行。
at java.net.SocketInputStream.read(SocketInputStream.java:129)
SocketInputStream 类名
read 方法名
SocketInputStream.java 源文件
129 源文件中的行数

在堆栈的第一行信息中,进一步标明了线程在代码级的状态,例如:

java.lang.Thread.State: TIMED_WAITING (parking)

解释如下:

|blocked|

This thread tried to enter asynchronized block, but the lock was taken by another thread. This thread isblocked until the lock gets released.

|blocked (on thin lock)|

This is the same state asblocked, but the lock in question is a thin lock.

|waiting|

This thread calledObject.wait() on an object. The thread will remain there until some otherthread sends a notification to that object.

|sleeping|

This thread calledjava.lang.Thread.sleep().

|parked|

This thread calledjava.util.concurrent.locks.LockSupport.park().

|suspended|

The thread's execution wassuspended by java.lang.Thread.suspend() or a JVMTI agent call.
本地线程ID

"NativeThread ID"所指的本地线程是指该java虚拟机所对应的虚拟机中的本地线程,java代码是依附于java虚拟机的本地线程执行的,当启动一个线程时,是创建一个native本地线程,本地线程才是真实的线程实体,为了更加深入理解本地线程和java线程的关系,可以通过以下方式将java虚拟机的本地线程打印出来:
1、试用ps -ef|grep java 获得java进行id
2、试用pstack 获得java虚拟机本地线程的堆栈
从操作系统打印出来的虚拟机的本地线程看,本地线程数量和java线程数量是相同的,说明二者是一一对应的关系。
那么本地线程号如何与java线程堆栈文件对应起来呢,每一个线程都有tid,nid的属性。nid即为dump线程的nid。

原文参考地址

你可能感兴趣的:(如何使用 thread dump?如何分析Thread dump?)