天天看點

Java堆轉儲:您可以完成任務嗎?

如果您像我一樣對Java性能充滿熱情,那麼堆轉儲分析對您來說應該不是一個謎。 如果是這樣,那麼好消息是您将有機會提高您的Java故障診斷技能和JVM知識。

JVM現已發展到今天,與舊的JDK 1.0 – JDK 1.4天相比,今天生成和分析JVM堆轉儲要容易得多。

堆轉儲分析不應視為替代配置檔案和JVM分析工具(例如JProfiler或Plumbr),而是可以互補的。 在對Java堆記憶體洩漏和java.lang.OutOfMemoryError問題進行故障排除時,此功能特别有用。

這篇文章将為您提供JVM堆轉儲的概述以及對它的期望。 它還将提供有關如何以及何時應該花時間分析堆轉儲的建議。 未來的文章将包括有關分析過程本身的教程。

Java堆轉儲概述

JVM堆轉儲基本上是給定時間的Java堆記憶體的“快照”。 它與作為線程快照的JVM線程轉儲完全不同。

此類快照包含有關Java對象和在Java堆上配置設定的類的低級詳細資訊,例如:

  • Java對象,例如Class,字段,原始值和引用
  • 與類加載器相關的資料,包括靜态字段(對于類加載器洩漏問題很重要)
  • 可從堆外部通路的垃圾收集根或對象(系統類加載器已加載資源,例如rt.jar,JNI或本機變量,線程,Java Locals等)
  • 與線程相關的資料和堆棧(對于突然出現的Java堆增加問題特别有用,尤其是與線程轉儲分析結合使用時)

請注意,通常建議在完整GC之後生成堆轉儲,以消除未引用對象中不必要的“噪音”。

分析保留給精英?

在過去的十年中,與生産支援團隊一起工作時,我發現一個普遍的誤解是給人留下深刻印象,即更深入的分析任務(例如性能分析,堆轉儲或線程轉儲分析)留給了“精英”或産品供應商(Oracle,IBM等)。 。

我完全不同意。

作為Java開發人員,您編寫的代碼可能在高度并發的線程環境中運作,進而在JVM上管理數百個對象。 您不僅要擔心并發問題,還要擔心垃圾回收和應用程式的記憶體占用。 由于您是應用程式的專家,是以您處于執行此分析的最佳位置。

Java堆轉儲:您可以完成任務嗎?

在下面找到您應該能夠回答的典型問題:

  • 根據負載預測,需要多少個并發線程來并發運作我的應用程式? 每個活動線程在完成任務之前要消耗多少記憶體?
  • 我的應用程式的靜态記憶體占用量是多少? (庫,類加載器占用空間,記憶體中緩存資料結構等)
  • 負載下我的應用程式的動态記憶體占用量是多少? (會話足迹等)
  • 您是否對應用程式進行了概要分析,以防記憶體洩漏?

負載測試,對應用程式進行性能分析以及分析Java堆轉儲(例如:在負載測試或生産問題期間捕獲)将使您能夠回答上述問題。 然後,您将可以實作以下目标:

  • 降低生産實施後出現性能問題的風險
  • 通過為生産和産能管理團隊提供額外的指導和事實,為您的工作和客戶增加價值; 允許他們采取适當的IT改進措施
  • 分析影響客戶IT生産環境的記憶體洩漏或占用空間問題的根本原因
  • 通過學習這些性能分析原理和技術來提高您的技術技能
  • 通過提高您對JVM,垃圾回收和Java對象生命周期的了解來提高JVM技能

您想要了解的最後一件事是技能“高原”。 如果您不喜歡這種類型的分析,那麼我的建議如下:

  • 要求團隊中更進階的成員執行堆轉儲分析并确定他的工作和方法
  • 一旦您感到更自在,就請自己自願執行相同的分析(針對不同的問題案例),這一次請一位經驗豐富的成員來完成您的分析工作
  • 最終,學生(您)将成為導師

何時使用

每次遇到Java堆問題(例如OutOfMemoryError)時,都不應分析JVM堆轉儲。 由于這可能是一個耗時的分析過程,是以我建議針對以下情況進行此分析:

  • 需要了解和調整您的應用程式和/或周圍的API或Java EE容器本身的記憶體占用量
  • Java堆記憶體洩漏故障排除
  • Java類加載器記憶體洩漏
  • 突然的Java堆增加問題或觸發事件(必須與線程轉儲分析結合起來作為起點)

現在,在下面找到與堆轉儲分析相關的一些限制:

  • JVM堆轉儲生成是一項繁重的計算任務,它将使您的JVM挂起直到完成。 需要進行适當的盡職調查,以減少對生産環境的影響
  • 分析堆轉儲不會提供完整的Java程序記憶體占用量,例如本機堆。 為此,您将需要依賴其他工具和OS指令
  • 您可能會遇到打開和解析從舊版本的JDK(例如1.4或1.5)生成的堆轉儲時遇到的問題

堆轉儲生成技術

JVM堆轉儲通常是通過以下2個操作生成的:

  • 由于java.lang.OutOfMemoryError(例如Java Heap,PermGen或本機堆耗盡)而自動生成或觸發
  • 通過使用諸如jmap,VisualVM(通過JMX)或OS級指令之類的工具手動生成

#自動觸發的堆轉儲

如果您使用的是HotSpot Java VM 1.5+或JRockit R28 +,則需要在JVM啟動時在下面添加以下參數:

-XX:+HeapDumpOnOutOfMemoryError
           

上面的參數将使HotSpot VM在OOM事件之後自動生成堆轉儲。 這些JVM類型的堆轉儲格式為HPROF(* .hprof)。

如果您使用的是IBM JVM 1.4.2+,那麼預設情況下會啟用OOM事件導緻的堆轉儲。 IBM JVM的堆轉儲格式為PHD(* .phd)。

#手動觸發的堆轉儲

可以按以下方式手動生成JVM堆轉儲:

  • jmap在HotSpot 1.5+中的使用
  • VisualVM for HotSpot 1.6+的使用*推薦*

**請對您的生産環境進行适當的盡職調查,因為JVM堆轉儲生成是一個侵入性過程,它将使您的JVM程序挂起直到完成**

如果使用的是IBM JVM 1.4.2,則需要從JVM啟動中添加以下環境變量:

export IBM_HEAPDUMP=true
export IBM_HEAP_DUMP=true
           

對于IBM JVM 1.5+,您将需要在Java啟動時添加以下參數:

-Xdump:heap
           

例如:

java -Xdump:none -Xdump:heap:events=vmstop,opts=PHD+CLASSIC
JVMDUMP006I Processing Dump Event 'vmstop', detail '#00000000' - Please Wait.
JVMDUMP007I JVM Requesting Heap Dump using
'C:\sdk\jre\bin\heapdump.20050323.142011.3272.phd'
JVMDUMP010I Heap Dump written to
C:\sdk\jre\bin\heapdump.20050323.142011.3272.phd
JVMDUMP007I JVM Requesting Heap Dump using
'C:\sdk\jre\bin\heapdump.20050323.142011.3272.txt'
JVMDUMP010I Heap Dump written to
C:\sdk\jre\bin\heapdump.20050323.142011.3272.txt
JVMDUMP013I Processed Dump Event 'vmstop', detail '#00000000'.
           

請檢視IBM JVM1.5 +的Xdump文檔。

對于Linux和AIX®,通過kill –QUIT或kill -3發送IBM JVM堆轉儲信号。 此OS指令将觸發JVM堆轉儲生成(PHD格式)。

我建議您檢視MAT摘要頁面,以了解如何通過各種JVM和OS組合擷取JVM堆轉儲。

堆轉儲分析工具

我推薦的用于打開和分析JVM堆轉儲的主要工具是Eclipse Memory Analyzer (MAT)。 到目前為止,這是SAP和IBM等貢獻者中最好的工具。 該工具提供了豐富的界面和先進的堆轉儲分析功能,其中包括“洩漏可疑”報告。 MAT還支援HPROF和PHD堆轉儲格式。

我建議在較早的文章中獲得有關如何使用MAT和分析您的第一個JVM堆轉儲的快速教程 。 我也有一些堆轉儲分析案例研究對您的學習過程很有用。

Java堆轉儲:您可以完成任務嗎?

最後的話

我真的希望您能像我一樣喜歡JVM堆轉儲分析。 以後的文章将為您提供有關如何分析JVM堆轉儲以及從何處開始的通用教程。 請随時提供您的意見。

參考: Java堆轉儲:您可以完成任務嗎? 從我們的JCG合作夥伴 Pierre-Hugues Charbonneau在Java EE支援模式和Java教程部落格中獲得。

翻譯自: https://www.javacodegeeks.com/2012/11/java-heap-dump-are-you-up-to-the-task.html