浅谈线程dump

安利

1、什么是java线程dump?

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

其中:

1.       线程的一些基本信息:名称、优先级及id

2.       线程状态:waiting on condition

3.       线程的调用栈

4.       线程锁住的资源:locked <0x3f63d600>

JVM中的许多问题都可以使用线程dump文件来进行诊断,其中比较典型的包括线程阻塞,CPU使用率过高,JVM Crash,堆内存不足和类装载等问题。 

2、如何生成?

不同的操作系统下,产生线程dump的方式是不同的:

1)         在 windows环境中

    在启动程序的控制台里敲: Ctrl - Break,线程的 dump会产生在标准输出中(缺省标准输出就是控制台,如果对输出进行了重定向,则要查看输出文件)。

2)         在 unix, linux和 MacOS 环境中

    在控制台中敲: Ctrl-\,或者,用“kill -3 <pid>”,或者“kill –QUIT <pid>”。 Pid是用所关注的 JAVA进程号,您可以用“ps -ef | grep java”找到,或者使用 JDK 5.0中的“jps -v”命令获得。

3)         在各个操作系统平台,都可以用 JDK 5.0工具包中的 jstack <pid>

这里要注意的是:

1.       不同的 JAVA虚机的线程 DUMP的创建方法和文件格式是不一样的,不同的 JVM版本, dump信息也有差别。本文中,只以 SUN的hotspot JVM 5.0_06 为例。

在实际运行中,往往一次 dump的信息,还不足以确认问题。建议产生三次 dump信息,如果每次 dump都指向同一个问题,我们才确定问题的典型性。

3、调用修饰

表示线程在方法调用时额外的重要操作。线程dump分析的重要信息,修饰上方的方法调用。

1、locked<地址>目标:使用synchronized申请对象锁成功,监视器的拥有者; 
2、waiting to lock<地址>目标:使用synchronized申请对象锁未成功,在进入区等待; 
3、waiting on<地址>目标:使用synchronized申请对象锁成功后,调用了wait方法,进入对象的等待区等待。在调用栈顶出线,线程状态为WAITING或TIMED_WAITING; 
4、parking to wait for<地址>目标:park是基本的线程阻塞原语,不通过监视器在对象上阻塞。随concurrent包出现的新的机制,与synchronized体系不同;

4、线程状态 

想要通过jstack命令来分析线程的情况的话,首先要知道线程都有哪些状态,下面这些状态是我们使用jstack命令查看线程堆栈信息时可能会看到的线程的几种状态:

1、NEW,未启动的。不会出现在Dump中。 
2、RUNNABLE,在虚拟机内执行的。 
3、BLOCKED,受阻塞并等待监视器锁。 
4、WATING,无限期等待另一个线程执行特定操作。 
5、TIMED_WATING,有时限的等待另一个线程的特定操作。 
6、TERMINATED,已退出的。


5、线程动作

线程状态产生的原因:

1、runnable:状态一般为RUNNABLE,表示线程具备所有运行条件,在运行队列中准备操作系统的调度,或者正在运行。 
2、in Object.wait():等待区等待,状态为WAITING或TIMED_WAITING。 
3、waiting for monitor entry:进入区等待,状态为BLOCKED。 
4、waiting on condition:等待去等待,被park。 
5、sleeping:休眠的线程,调用了Thread.sleep()。

频繁GC问题或内存溢出问题 
一、使用jps查看线程ID 
二、使用jstat -gc 3331 250 20 查看gc情况,一般比较关注PERM区的情况,查看GC的增长情况。 
三、使用jstat -gccause:额外输出上次GC原因 
四、使用jmap -dump:format=b,file=heapDump 3331生成堆转储文件 
五、使用jhat或者可视化工具(Eclipse Memory Analyzer 、IBM HeapAnalyzer)分析堆情况。 
六、结合代码解决内存溢出或泄露问题。 

死锁问题 
一、使用jps查看线程ID 
二、使用jstack 3331:查看线程情况

猜你喜欢

转载自blog.csdn.net/hjing123/article/details/88963282