JVM:如何分析线程转储
我的目標(biāo)是與您分享我在過去10年中積累的有關(guān)線程轉(zhuǎn)儲分析的知識,例如數(shù)百個線程轉(zhuǎn)儲分析周期以及許多JVM版本和JVM供應(yīng)商之間的數(shù)十種常見問題模式。
請為此頁面添加書簽,并隨時關(guān)注每周的文章。
也請隨時與您的工作同事和朋友分享此Thread Dump培訓(xùn)計劃。
聽起來不錯,我真的需要提高我的Thread Dump技能……那么我們從哪里開始呢?
我向您提出的是一個完整的“線程轉(zhuǎn)儲”培訓(xùn)計劃。 將涵蓋以下項目。 我還將為您提供現(xiàn)實的線程轉(zhuǎn)儲示例,您可以學(xué)習(xí)和理解。
1)線程轉(zhuǎn)儲概述和基礎(chǔ)知識
2)線程轉(zhuǎn)儲生成技術(shù)和可用工具
3)Sun HotSpot,IBM JRE和Oracle JRockit之間的線程轉(zhuǎn)儲格式差異 4)線程堆棧跟蹤的解釋和解釋 5)線程轉(zhuǎn)儲分析和相關(guān)技術(shù) 6)線程轉(zhuǎn)儲常見問題模式(線程爭用,死鎖,掛起IO調(diào)用,垃圾回收/ OutOfMemoryError問題,無限循環(huán)等) 7)通過實際案例研究得出的線程轉(zhuǎn)儲示例
我真的希望這個線程轉(zhuǎn)儲分析培訓(xùn)計劃對您有所幫助,所以請繼續(xù)關(guān)注每周更新和文章!
但是,如果我仍然有疑問或仍在努力理解這些培訓(xùn)文章怎么辦?
不用擔(dān)心,請考慮我為您的培訓(xùn)師。 我強(qiáng)烈建議您向我提問關(guān)于Thread Dump的任何問題 ( 請記住,沒有愚蠢的問題 ),因此,我免費為您提供以下選擇; 只需選擇您更熟悉的通信模型即可:
1)通過在文章下方發(fā)布您的評論來提交與主題轉(zhuǎn)儲相關(guān)的問題( 請隨時保持匿名 )
2)將線程轉(zhuǎn)儲數(shù)據(jù)提交到根本原因分析論壇
3)給我發(fā)電子郵件與您的主題轉(zhuǎn)儲相關(guān)的問題@ phcharbonneau@hotmail.com
我可以從生產(chǎn)環(huán)境/服務(wù)器向您發(fā)送線程轉(zhuǎn)儲數(shù)據(jù)嗎?
是的,如果您希望討論問題的根本原因,請隨時通過電子郵件或“ 根本原因分析”論壇將您生成的線程轉(zhuǎn)儲數(shù)據(jù)發(fā)送給我。 現(xiàn)實生活中的線程轉(zhuǎn)儲分析始終是最好的學(xué)習(xí)方法。
我真的希望您會喜歡并分享此線程轉(zhuǎn)儲分析培訓(xùn)計劃。 我將盡力為您提供優(yōu)質(zhì)的材料和任何問題的答案。
在深入研究線程轉(zhuǎn)儲分析和問題模式之前,了解基礎(chǔ)知識非常重要。 該文章將介紹基礎(chǔ)知識,并讓您更好地與Java EE容器進(jìn)行JVM和中間件交互。
Java VM概述
Java虛擬機(jī)實際上是任何Java EE平臺的基礎(chǔ)。 這是您的中間件和應(yīng)用程序已部署并處于活動狀態(tài)的地方。
JVM為中間件軟件和Java / Java EE程序提供以下功能:
– Java / Java EE程序的運行時環(huán)境(字節(jié)碼格式)
–幾個程序功能和實用程序(IO設(shè)施,數(shù)據(jù)結(jié)構(gòu),線程管理,安全性,監(jiān)視等)
–通過垃圾回收器動態(tài)分配和管理內(nèi)存
您的JVM可以駐留在許多操作系統(tǒng)(Solaris,AIX,Windows等)上,并且根據(jù)您的物理服務(wù)器規(guī)格,您可以為每個物理/虛擬服務(wù)器安裝1…n個JVM進(jìn)程。
JVM和中間件軟件交互
在下面找到一個圖,該圖向您顯示JVM,中間件和應(yīng)用程序之間的高級交互視圖。
這向您展示了JVM,中間件和應(yīng)用程序之間的典型且簡單的交互圖。 如您所見,標(biāo)準(zhǔn)Java EE應(yīng)用程序的線程分配主要在中間件內(nèi)核本身和JVM之間完成( 當(dāng)應(yīng)用程序本身或某些API直接創(chuàng)建線程時會有一些例外,但這并不常見,必須非常小心地完成 ) 。
另外,請注意,某些線程是在JVM自身內(nèi)部進(jìn)行管理的,例如GC(垃圾收集)線程,以便處理并發(fā)垃圾收集。
由于大多數(shù)線程分配是由Java EE容器完成的,因此了解并識別線程堆棧跟蹤并從線程轉(zhuǎn)儲數(shù)據(jù)中正確識別它很重要,這一點很重要。 這將使您快速了解Java EE容器嘗試執(zhí)行的請求的類型。
從線程轉(zhuǎn)儲分析的角度,您將學(xué)習(xí)如何區(qū)分從JVM找到的不同線程池并確定請求類型。
最后一部分將為您概述什么是HotSpot VM的JVM線程轉(zhuǎn)儲以及您將找到的不同線程。 第4部分將提供IBM VM線程轉(zhuǎn)儲格式的詳細(xì)信息。
請注意,您可以從根本原因分析論壇中找到本文使用的線程轉(zhuǎn)儲示例。
JVM線程轉(zhuǎn)儲–這是什么?
JVM線程轉(zhuǎn)儲是在給定時間拍攝的快照,可為您提供所有已創(chuàng)建的Java線程的完整列表。
找到的每個單獨的Java線程都會為您提供以下信息:
– 線程名稱 ; 通常由中間件供應(yīng)商用于標(biāo)識線程ID及其關(guān)聯(lián)的線程池名稱和狀態(tài)(運行,阻塞等)。
– 線程類型和優(yōu)先級,例如: 守護(hù)程序prio = 3 **中間件軟件通常將其線程創(chuàng)建為守護(hù)程序,這意味著它們的線程在后臺運行; 向用戶提供服務(wù),例如您的Java EE應(yīng)用程序**
– Java線程ID,例如: tid = 0x000000011e52a800 **這是通過java.lang.Thread.getId()獲得的Java線程ID,通常以自動遞增long 1..n **的形式實現(xiàn)
–本機(jī)線程ID,例如: nid = 0x251c **作為本機(jī)線程ID的重要信息,您可以關(guān)聯(lián)例如從OS角度來看哪個線程在JVM中使用最多的CPU等。
– Java線程狀態(tài)和詳細(xì)信息,例如: 等待監(jiān)視器條目[0xfffffffea5afb000] java.lang.Thread.State:已阻止(在對象監(jiān)視器上)
**允許快速了解線程狀態(tài)及其潛在的電流阻塞條件**
– Java線程堆棧跟蹤 ; 這是迄今為止從線程轉(zhuǎn)儲中找到的最重要的數(shù)據(jù)。 這也是您將花費大部分時間的地方,因為Java Stack Trace為您提供了90%的信息,以便查明許多問題模式類型的根本原因,您將在稍后的培訓(xùn)課程中學(xué)習(xí)
– Java堆故障 ; 從HotSpot VM 1.6開始,您還將在“線程轉(zhuǎn)儲”快照的底部找到HotSpot內(nèi)存空間利用率的細(xì)目分類,例如Java堆(YoungGen,OldGen)和PermGen空間。 當(dāng)懷疑過多的GC是可能的根本原因時,此功能非常有用,因此您可以對找到的線程數(shù)據(jù)/模式進(jìn)行開箱即用的關(guān)聯(lián)
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)線程轉(zhuǎn)儲故障概覽
為了使您更好地理解,請在下面的圖表中直觀地查看HotSpot VM線程轉(zhuǎn)儲及其常見的線程池:
您可以從HotSpot VM線程轉(zhuǎn)儲中找到一些信息。 根據(jù)您的問題模式,其中一些功能比其他功能更重要(問題模式將在以后的文章中進(jìn)行模擬和解釋)。現(xiàn)在,根據(jù)我們的示例 HotSpot線程轉(zhuǎn)儲,在下面找到每個線程轉(zhuǎn)儲部分的詳細(xì)說明:
#全線程轉(zhuǎn)儲標(biāo)識符
基本上,這是唯一的關(guān)鍵字,一旦生成線程轉(zhuǎn)儲(例如:對于UNIX,通過kill -3 <PID>),您就會在中間件/標(biāo)準(zhǔn)Java輸出日志中找到該關(guān)鍵字。 這是“線程轉(zhuǎn)儲”快照數(shù)據(jù)的開始。
#Java EE中間件,第三方和自定義應(yīng)用程序線程
這部分是線程轉(zhuǎn)儲的核心,通常您將在其中花費大部分分析時間。 找到的線程數(shù)將取決于您使用的中間件軟件,第三方庫(可能具有其自己的線程)和您的應(yīng)用程序( 如果創(chuàng)建任何自定義線程,通常不是最佳實踐 )。
在我們的示例線程轉(zhuǎn)儲中,Weblogic是所使用的中間件。 從Weblogic 9.2開始,使用具有唯一標(biāo)識符“'weblogic.kernel.Default(自我調(diào)整)”的自我調(diào)整線程池。
"[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管理的內(nèi)部線程,以執(zhí)行內(nèi)部本機(jī)操作。 通常,除非看到較高的CPU(通過線程轉(zhuǎn)儲和prstat /本機(jī)線程ID相關(guān)性),否則您不必?fù)?dān)心這一點。
#HotSpot GC線程
當(dāng)使用HotSpot并行GC時(在使用多物理核心硬件時,這很普遍),默認(rèn)情況下或根據(jù)JVM調(diào)整一定數(shù)量的GC線程,HotSpot VM會創(chuàng)建。 這些GC線程允許VM以并行方式執(zhí)行其定期GC清理,從而總體上減少了GC時間。 以增加CPU利用率為代價。
這也是至關(guān)重要的數(shù)據(jù),因為當(dāng)面臨與GC相關(guān)的問題(例如過多的GC,內(nèi)存泄漏等)時,您將能夠使用其本機(jī)id值(nid)將從OS / Java進(jìn)程觀察到的任何高CPU與這些線程相關(guān)聯(lián)= 0x3)。 您將在以后的文章中學(xué)習(xí)如何識別和確認(rèn)此問題。
#JNI全局引用計數(shù)
JNI(Java本機(jī)接口)全局引用基本上是從本機(jī)代碼到Java垃圾收集器管理的Java對象的對象引用。 其作用是防止收集本機(jī)代碼仍在使用但技術(shù)上在Java代碼中沒有“實時”引用的對象。
監(jiān)視JNI引用以檢測與JNI相關(guān)的泄漏也很重要。 如果您直接使用JNI進(jìn)行編程,或者使用易于發(fā)生本機(jī)內(nèi)存泄漏的第三方工具(例如監(jiān)視工具)進(jìn)行編程,則可能會發(fā)生這種情況。
JNI global references: 1925 #Java堆利用率視圖
此數(shù)據(jù)已添加回JDK 1 .6,并為您提供了HotSpot Heap的簡短快速視圖。 我發(fā)現(xiàn)在與GC相關(guān)的問題以及HIGH CPU一起進(jìn)行故障排除時,它非常有用,因為您可以在單個快照中同時獲得線程轉(zhuǎn)儲和Java堆,從而可以確定(或排除)特定Java堆內(nèi)存空間中的任何壓力點以及當(dāng)前當(dāng)時正在執(zhí)行線程計算。 正如您在示例線程轉(zhuǎn)儲中所看到的,Java堆OldGen已被最大化!
我希望本文有助于理解HotSpot VM線程轉(zhuǎn)儲的基本視圖。下一篇文章將為您提供與IBM VM相同的線程轉(zhuǎn)儲概述和細(xì)分。
請隨時發(fā)表任何評論或問題。
參考: 如何分析線程轉(zhuǎn)儲–第1部分 , ? 如何分析線程轉(zhuǎn)儲–第2部分:JVM概述和 如何分析線程轉(zhuǎn)儲–第3部分: 來自JCG合作伙伴的 HotSpot VM ? “ Java EE支持模式和Java教程”博客上的Pierre-Hugues Charbonneau。
翻譯自: https://www.javacodegeeks.com/2012/03/jvm-how-to-analyze-thread-dump.html
總結(jié)
以上是生活随笔為你收集整理的JVM:如何分析线程转储的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 朝朝盈钱不见了怎么回事?
- 下一篇: 嵌入式码头,Vaadin和焊接