我的目標是與您分享我在過去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