我的目标是与您分享我在过去10年中积累的有关线程转储分析的知识,例如数百个线程转储分析周期以及许多JVM版本和JVM供应商之间的数十种常见问题模式。
请为此页面添加书签,并随时关注每周的文章。
也请随时与您的工作同事和朋友分享此Thread Dump培训计划。
听起来不错,我真的需要提高我的Thread Dump技能……那么我们从哪里开始呢?
我向您提出的是一个完整的“线程转储”培训计划。 将涵盖以下项目。 我还将为您提供现实的线程转储示例,您可以学习和理解。
1)线程转储概述和基础知识
2)线程转储生成技术和可用工具
3)Sun HotSpot,IBM JRE和Oracle JRockit之间的线程转储格式差异 4)线程堆栈跟踪的解释和解释 5)线程转储分析和相关技术 6)线程转储常见问题模式(线程争用,死锁,挂起IO调用,垃圾回收/ OutOfMemoryError问题,无限循环等) 7)通过实际案例研究得出的线程转储示例
我真的希望这个线程转储分析培训计划对您有所帮助,所以请继续关注每周更新和文章!
但是,如果我仍然有疑问或仍在努力理解这些培训文章怎么办?
不用担心,请考虑我为您的培训师。 我强烈建议您向我提问关于Thread Dump的任何问题 ( 请记住,没有愚蠢的问题 ),因此,我免费为您提供以下选择; 只需选择您更熟悉的通信模型即可:
1)通过在文章下方发布您的评论来提交与主题转储相关的问题( 请随时保持匿名 )
2)将线程转储数据提交到根本原因分析论坛
3)给我发电子邮件与您的主题转储相关的问题@ phcharbonneau@hotmail.com
我可以从生产环境/服务器向您发送线程转储数据吗?
是的,如果您希望讨论问题的根本原因,请随时通过电子邮件或“ 根本原因分析”论坛将您生成的线程转储数据发送给我。 现实生活中的线程转储分析始终是最好的学习方法。
我真的希望您会喜欢并分享此线程转储分析培训计划。 我将尽力为您提供优质的材料和任何问题的答案。
在深入研究线程转储分析和问题模式之前,了解基础知识非常重要。 该文章将介绍基础知识,并让您更好地与Java EE容器进行JVM和中间件交互。
Java VM概述
Java虚拟机实际上是任何Java EE平台的基础。 这是您的中间件和应用程序已部署并处于活动状态的地方。
JVM为中间件软件和Java / Java EE程序提供以下功能:
– Java / Java EE程序的运行时环境(字节码格式)
–几个程序功能和实用程序(IO设施,数据结构,线程管理,安全性,监视等)
–通过垃圾回收器动态分配和管理内存
您的JVM可以驻留在许多操作系统(Solaris,AIX,Windows等)上,并且根据您的物理服务器规格,您可以为每个物理/虚拟服务器安装1…n个JVM进程。
JVM和中间件软件交互
在下面找到一个图,该图向您显示JVM,中间件和应用程序之间的高级交互视图。
这向您展示了JVM,中间件和应用程序之间的典型且简单的交互图。 如您所见,标准Java EE应用程序的线程分配主要在中间件内核本身和JVM之间完成( 当应用程序本身或某些API直接创建线程时会有一些例外,但这并不常见,必须非常小心地完成 ) 。
另外,请注意,某些线程是在JVM自身内部进行管理的,例如GC(垃圾收集)线程,以便处理并发垃圾收集。
由于大多数线程分配是由Java EE容器完成的,因此了解并识别线程堆栈跟踪并从线程转储数据中正确识别它很重要,这一点很重要。 这将使您快速了解Java EE容器尝试执行的请求的类型。
从线程转储分析的角度,您将学习如何区分从JVM找到的不同线程池并确定请求类型。
最后一部分将为您概述什么是HotSpot VM的JVM线程转储以及您将找到的不同线程。 第4部分将提供IBM VM线程转储格式的详细信息。
请注意,您可以从根本原因分析论坛中找到本文使用的线程转储示例。
JVM线程转储–这是什么?
JVM线程转储是在给定时间拍摄的快照,可为您提供所有已创建的Java线程的完整列表。
找到的每个单独的Java线程都会为您提供以下信息:
– 线程名称 ; 通常由中间件供应商用于标识线程ID及其关联的线程池名称和状态(运行,阻塞等)。
– 线程类型和优先级,例如: 守护程序prio = 3 **中间件软件通常将其线程创建为守护程序,这意味着它们的线程在后台运行; 向用户提供服务,例如您的Java EE应用程序**
– Java线程ID,例如: tid = 0x000000011e52a800 **这是通过java.lang.Thread.getId()获得的Java线程ID,通常以自动递增long 1..n **的形式实现
–本机线程ID,例如: nid = 0x251c **作为本机线程ID的重要信息,您可以关联例如从OS角度来看哪个线程在JVM中使用最多的CPU等。
– Java线程状态和详细信息,例如: 等待监视器条目[0xfffffffea5afb000] java.lang.Thread.State:已阻止(在对象监视器上)
**允许快速了解线程状态及其潜在的电流阻塞条件**
– Java线程堆栈跟踪 ; 这是迄今为止从线程转储中找到的最重要的数据。 这也是您将花费大部分时间的地方,因为Java Stack Trace为您提供了90%的信息,以便查明许多问题模式类型的根本原因,您将在稍后的培训课程中学习
– Java堆故障 ; 从HotSpot VM 1.6开始,您还将在“线程转储”快照的底部找到HotSpot内存空间利用率的细目分类,例如Java堆(YoungGen,OldGen)和PermGen空间。 当怀疑过多的GC是可能的根本原因时,此功能非常有用,因此您可以对找到的线程数据/模式进行开箱即用的关联
Heap
PSYoungGen total 466944K, used 178734K [0xffffffff45c00000, 0xffffffff70800000, 0xffffffff70800000)
eden space 233472K, 76% used [0xffffffff45c00000,0xffffffff50ab7c50,0xffffffff54000000)
from space 233472K, 0% used [0xffffffff62400000,0xffffffff62400000,0xffffffff70800000)
to space 233472K, 0% used [0xffffffff54000000,0xffffffff54000000,0xffffffff62400000)
PSOldGen total 1400832K, used 1400831K [0xfffffffef0400000, 0xffffffff45c00000, 0xffffffff45c00000)
object space 1400832K, 99% used [0xfffffffef0400000,0xffffffff45bfffb8,0xffffffff45c00000)
PSPermGen total 262144K, used 248475K [0xfffffffed0400000, 0xfffffffee0400000, 0xfffffffef0400000)
object space 262144K, 94% used [0xfffffffed0400000,0xfffffffedf6a6f08,0xfffffffee0400000)
线程转储故障概览
为了使您更好地理解,请在下面的图表中直观地查看HotSpot VM线程转储及其常见的线程池:
现在,根据我们的示例 HotSpot线程转储,在下面找到每个线程转储部分的详细说明:
#全线程转储标识符
基本上,这是唯一的关键字,一旦生成线程转储(例如:对于UNIX,通过kill -3 <PID>),您就会在中间件/标准Java输出日志中找到该关键字。 这是“线程转储”快照数据的开始。
Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.0-b11 mixed mode):
#Java EE中间件,第三方和自定义应用程序线程
这部分是线程转储的核心,通常您将在其中花费大部分分析时间。 找到的线程数将取决于您使用的中间件软件,第三方库(可能具有其自己的线程)和您的应用程序( 如果创建任何自定义线程,通常不是最佳实践 )。
在我们的示例线程转储中,Weblogic是所使用的中间件。 从Weblogic 9.2开始,使用具有唯一标识符“'weblogic.kernel.Default(自我调整)”的自我调整线程池。
"[STANDBY] ExecuteThread: '414' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=3 tid=0x000000010916a800 nid=0x2613 in Object.wait() [0xfffffffe9edff000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0xffffffff27d44de0> (a weblogic.work.ExecuteThread)at java.lang.Object.wait(Object.java:485)at weblogic.work.ExecuteThread.waitForRequest(ExecuteThread.java:160)- locked <0xffffffff27d44de0> (a weblogic.work.ExecuteThread)at weblogic.work.ExecuteThread.run(ExecuteThread.java:181)
#HotSpot VM线程
这是由HotSpot VM管理的内部线程,以执行内部本机操作。 通常,除非看到较高的CPU(通过线程转储和prstat /本机线程ID相关性),否则您不必担心这一点。
"VM Periodic Task Thread" prio=3 tid=0x0000000101238800 nid=0x19 waiting on condition
#HotSpot GC线程
当使用HotSpot并行GC时(在使用多物理核心硬件时,这很普遍),默认情况下或根据JVM调整一定数量的GC线程,HotSpot VM会创建。 这些GC线程允许VM以并行方式执行其定期GC清理,从而总体上减少了GC时间。 以增加CPU利用率为代价。
"GC task thread#0 (ParallelGC)" prio=3 tid=0x0000000100120000 nid=0x3 runnable
"GC task thread#1 (ParallelGC)" prio=3 tid=0x0000000100131000 nid=0x4 runnable
………………………………………………………………………………………………………………………………………………………………
这也是至关重要的数据,因为当面临与GC相关的问题(例如过多的GC,内存泄漏等)时,您将能够使用其本机id值(nid)将从OS / Java进程观察到的任何高CPU与这些线程相关联= 0x3)。 您将在以后的文章中学习如何识别和确认此问题。
#JNI全局引用计数
JNI(Java本机接口)全局引用基本上是从本机代码到Java垃圾收集器管理的Java对象的对象引用。 其作用是防止收集本机代码仍在使用但技术上在Java代码中没有“实时”引用的对象。
监视JNI引用以检测与JNI相关的泄漏也很重要。 如果您直接使用JNI进行编程,或者使用易于发生本机内存泄漏的第三方工具(例如监视工具)进行编程,则可能会发生这种情况。
JNI global references: 1925
#Java堆利用率视图
此数据已添加回JDK 1 .6,并为您提供了HotSpot Heap的简短快速视图。 我发现在与GC相关的问题以及HIGH CPU一起进行故障排除时,它非常有用,因为您可以在单个快照中同时获得线程转储和Java堆,从而可以确定(或排除)特定Java堆内存空间中的任何压力点以及当前当时正在执行线程计算。 正如您在示例线程转储中所看到的,Java堆OldGen已被最大化!
HeapPSYoungGen total 466944K, used 178734K [0xffffffff45c00000, 0xffffffff70800000, 0xffffffff70800000)eden space 233472K, 76% used [0xffffffff45c00000,0xffffffff50ab7c50,0xffffffff54000000)from space 233472K, 0% used [0xffffffff62400000,0xffffffff62400000,0xffffffff70800000)to space 233472K, 0% used [0xffffffff54000000,0xffffffff54000000,0xffffffff62400000)PSOldGen total 1400832K, used 1400831K [0xfffffffef0400000, 0xffffffff45c00000, 0xffffffff45c00000)object space 1400832K, 99% used [0xfffffffef0400000,0xffffffff45bfffb8,0xffffffff45c00000)PSPermGen total 262144K, used 248475K [0xfffffffed0400000, 0xfffffffee0400000, 0xfffffffef0400000)object space 262144K, 94% used [0xfffffffed0400000,0xfffffffedf6a6f08,0xfffffffee0400000)
我希望本文有助于理解HotSpot VM线程转储的基本视图。下一篇文章将为您提供与IBM VM相同的线程转储概述和细分。
请随时发表任何评论或问题。
参考: 如何分析线程转储–第1部分 , 如何分析线程转储–第2部分:JVM概述和 如何分析线程转储–第3部分: 来自JCG合作伙伴的 HotSpot VM “ Java EE支持模式和Java教程”博客上的Pierre-Hugues Charbonneau。
翻译自: https://www.javacodegeeks.com/2012/03/jvm-how-to-analyze-thread-dump.html