如何分析线程转储–线程堆栈跟踪
為了使您能夠從線程轉儲中快速識別問題模式,首先需要了解如何讀取線程堆棧跟蹤以及如何正確獲取“故事”。 這意味著,如果我要您告訴我#38線程在做什么? 您應該能夠準確回答; 包括“線程堆棧跟蹤”是否顯示正常(正常)與掛起狀態。
再談Java堆棧跟蹤
你們中的大多數人都熟悉Java堆棧跟蹤。 當拋出Java異常時,這是我們從服務器和應用程序日志文件中找到的典型數據。 在這種情況下,Java堆棧跟蹤為我們提供了觸發Java異常的Thread的代碼執行路徑,例如java.lang.NoClassDefFoundError,java.lang.NullPpointerException等。此類代碼執行路徑使我們可以查看不同的層最終導致Java異常的代碼。
必須始終從下至上讀取Java堆棧跟蹤:
- 底部的行將顯示請求的始發者,例如Java / Java EE容器Thread。
- 堆棧跟蹤頂部的第一行將向您顯示觸發了最后一個Exception的Java類。
讓我們通過一個簡單的示例來完成此過程。 我們創建了一個示例Java程序,只需執行一些Class方法調用并拋出Exception。 生成的程序輸出如下:
JavaStrackTraceSimulator Author: Pierre-Hugues Charbonneau http://javaeesupportpatterns.blogspot.comException in thread "main" java.lang.IllegalArgumentException:at org.ph.javaee.training.td.Class2.call(Class2.java:12)at org.ph.javaee.training.td.Class1.call(Class1.java:14)at org.ph.javaee.training.td.JavaSTSimulator.main(JavaSTSimulator.java:20)- 調用Java程序JavaSTSimulator(通過“主”線程)
- 然后,模擬器從Class1調用方法call()
- 然后,Class1方法call()調用Class2方法call()
- Class2方法call()引發Java異常:java.lang.IllegalArgumentException
- 然后,在日志/標準輸出中顯示Java異常
如您所見,導致此異常的代碼執行路徑始終從下至上顯示。
上面的分析過程對于任何Java程序員都應該是眾所周知的。 接下來,您將看到線程轉儲線程堆棧跟蹤分析過程與上述Java堆棧跟蹤分析非常相似。
線程轉儲:線程堆棧跟蹤分析
從JVM生成的線程轉儲為您提供了整個JVM進程中所有“創建的”線程的代碼級執行快照。 創建線程并不意味著所有這些線程實際上都在做某事。 在從Java EE容器JVM生成的典型線程轉儲快照中:
- 一些線程可能正在執行原始計算任務,例如XML解析,IO /磁盤訪問等。
- 一些線程可能正在等待一些阻塞的IO調用,例如遠程Web服務調用,DB / JDBC查詢等。
- 那時某些線程可能涉及垃圾回收,例如GC線程
- 一些線程將等待一些工作要做(不做任何工作的線程通常進入wait()狀態)
- 一些線程可能正在等待其他一些線程完成工作,例如,一些線程正在等待獲取某些對象上的監視器鎖定(同步塊{})
在下一篇文章中,我將返回上面的更多圖表,但現在讓我們集中討論堆棧跟蹤分析過程。 您的下一個任務是能夠盡您所能讀取線程堆棧跟蹤并了解它在做什么。
線程堆棧跟蹤為您提供了其當前執行的快照。 第一行通常包含線程的本機信息,例如其名稱,狀態,地址等。當前執行堆棧跟蹤必須自下而上讀取。 請遵循以下分析過程。 您從線程轉儲分析中獲得的經驗越多,您就能越快地讀取并快速識別每個線程執行的工作:
- 從底部開始讀取線程堆棧跟蹤
- 首先,確定發起者(Java EE容器線程,自定義線程,GC線程,JVM內部線程,獨立的Java程序“主”線程等)。
- 下一步是確定線程正在執行的請求的類型(WebApp,Web Service,JMS,遠程EJB(RMI),內部Java EE容器等)。
- 下一步是從執行堆棧中識別出您所涉及的應用程序模塊的形式,例如,線程正在嘗試執行的實際核心工作。 分析的復雜性將取決于中間件環境和應用程序的抽象層
- 下一步是查看第一行之前的最后?10-20行。 標識線程所涉及的協議或工作,例如HTTP調用,套接字通信,JDBC或原始計算任務,例如磁盤訪問,類加載等。
- 下一步是看第一行。 第一行通常告訴LOT處于Thread狀態,因為它是您拍攝快照時執行的當前代碼
- 最后兩個步驟的組合將為您提供信息的核心,以總結線程所涉及的工作和/或懸掛條件
現在,使用從JBoss 5生產環境捕獲的Thread Dump Thread堆棧跟蹤的真實示例,在下面直觀地查看上述步驟。 在此示例中,許多線程在創建新的JAX-WS Service實例時都顯示了類似的問題,即IO過多。
如您所見,最后10行和第一行將告訴我們線程所涉及的掛起或緩慢狀態(如果有)。 底部的幾行將為我們提供發起者和請求類型的詳細信息。
我希望本文能幫助您了解正確的線程堆棧跟蹤分析的重要性。 當我們在以后的文章中介紹最常見的線程轉儲問題模式時,我將帶回更多的線程堆棧跟蹤示例。 現在,下一篇文章將教您如何在邏輯孤島中分解線程轉儲線程,并提出潛在的根本原因“可疑”列表。
參考: 如何分析線程轉儲–第5部分:來自JCG合作伙伴 Pierre-Hugues Charbonneau的Java EE支持模式和Java教程博客中的線程堆棧跟蹤 。
翻譯自: https://www.javacodegeeks.com/2012/07/how-to-analyze-thread-dump-thread-stack.html
總結
以上是生活随笔為你收集整理的如何分析线程转储–线程堆栈跟踪的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 长城守卫军有谁 谁是长城守卫军
- 下一篇: 与Maven 3,Failsafe和Ca