簡體   English   中英

"用於分析大型 Java 堆轉儲的工具"

[英]Tool for analyzing large Java heap dumps

我有一個想要分析的 HotSpot JVM 堆轉儲。 VM 使用-Xmx31g運行,堆轉儲文件大小為 48 GB。

  • 我什至不會嘗試jhat ,因為它需要大約五倍的堆內存(在我的情況下是 240 GB)並且非常慢。
  • 在分析堆轉儲幾個小時后,Eclipse MAT 崩潰並出現ArrayIndexOutOfBoundsException

還有哪些其他工具可用於該任務? 一套命令行工具是最好的,它由一個程序組成,將堆轉儲轉換為有效的數據結構以供分析,並結合其他幾個處理預結構化數據的工具。

通常,我使用的是包含在Eclipse 內存分析器中在此處描述的ParseHeapDump.sh ,我在我們更強大的服務器上執行此操作(下載並復制 linux .zip 發行版,然后在那里解壓縮)。 與從 GUI 解析堆相比,shell 腳本需要的資源更少,而且您可以在具有更多資源的強大服務器上運行它(您可以通過在末尾添加-vmargs -Xmx40g -XX:-UseGCOverheadLimit來分配更多資源腳本的最后一行。例如,該文件的最后一行修改后可能如下所示

./MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "$@" -vmargs -Xmx40g -XX:-UseGCOverheadLimit

./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof一樣運行它

成功后,它會在 .hprof 文件旁邊創建許多“索引”文件。

創建索引后,我嘗試從中生成報告並將這些報告 scp 到我的本地計算機,並嘗試查看是否可以僅通過該報告(不僅僅是報告,而不是索引)找到罪魁禍首。 這是有關創建報告的教程。

示例報告:

./ParseHeapDump.sh ../today_heap_dump/jvm.hprof org.eclipse.mat.api:suspects

其他報告選項:

org.eclipse.mat.api:overvieworg.eclipse.mat.api:top_components

如果這些報告還不夠,並且我需要更多的挖掘(即讓我們說通過 oql),我將索引以及 hprof 文件 scp 到我的本地機器,然后打開堆轉儲(索引與堆轉儲)與我的 Eclipse MAT GUI。 從那里,它不需要太多的內存來運行。

編輯:我只是喜歡添加兩個注釋:

  • 據我所知,只有索引的生成是 Eclipse MAT 的內存密集部分。 有了索引之后,大部分來自 Eclipse MAT 的處理就不需要那么多內存了。
  • 在 shell 腳本上執行此操作意味着我可以在無頭服務器上執行此操作(我通常也在無頭服務器上執行此操作,因為它們通常是最強大的服務器)。 如果您有一台可以生成這種大小的堆轉儲的服務器,很有可能您還有另一台服務器也可以處理如此多的堆轉儲。

第一步:增加分配給 MAT 的 RAM 量。 默認情況下,它不是很多,也無法打開大文件。

如果在 MAC (OSX) 上使用 MAT,您將在 MemoryAnalyzer.app/Contents/MacOS 中擁有文件 MemoryAnalyzer.ini 文件。 對該文件進行調整並讓它們“接受”對我來說不起作用。 您可以改為基於此文件的內容創建修改后的啟動命令/shell 腳本並從該目錄運行它。 就我而言,我想要 20 GB 堆:

./MemoryAnalyzer -vmargs -Xmx20g --XX:-UseGCOverheadLimit ... other params desired

只需通過終端從 Contents/MacOS 目錄運行此命令/腳本,即可使用更多可用 RAM 啟動 GUI。

這個相關問題的公認答案應該為您提供一個良好的開端(使用實時 jmap 直方圖而不是堆轉儲):

在大型Java堆轉儲中查找內存泄漏的方法

大多數其他堆分析器(我使用 IBM http://www.alphaworks.ibm.com/tech/heapanalyzer )如果您期待一個不錯的 GUI 工具,至少需要比堆多一定百分比的 RAM。

除此之外,許多開發人員使用替代方法,例如實時堆棧分析來了解正在發生的事情。

雖然我必須質疑為什么你的堆這么大? 對分配和垃圾收集的影響一定是巨大的。 我敢打賭,堆中的大部分內容實際上應該存儲在數據庫/持久緩存等中。

我建議嘗試 YourKit。 它通常需要比堆轉儲大小少一點的內存(它索引它並使用該信息來檢索你想要的)

還有幾個選項:

此人http://blog.ragozin.info/2015/02/programatic-heapdump-analysis.html

編寫了一個自定義的 Netbeans 堆分析器,它只是通過堆轉儲文件公開一個“查詢樣式”接口,而不是實際將文件加載到內存中。

https://github.com/aragozin/jvm-tools/tree/master/hprof-heap

雖然我不知道“他的查詢語言”是否比這里接受的答案中提到的 eclipse OQL 更好。

據說JProfiler 8.1(用戶許可證 499 美元)還可以在不使用大量資金的情況下遍歷大型堆。

一個不太知名的工具 - http://dr-brenschede.de/bheapsampler/適用於大堆。 它通過采樣工作,因此它不必閱讀整個內容,盡管有點挑剔。

Eclipse Memory Analyzer 的最新快照版本具有隨機丟棄一定百分比的對象以減少內存消耗並允許分析剩余對象的功能。 請參閱錯誤 563960夜間快照構建,以在下一個 MAT 版本中包含此功能之前對其進行測試。

這不是命令行解決方案,但我喜歡這些工具:

將堆轉儲復制到足以承載它的服務器。 很可能可以使用原始服務器。

通過輸入服務器ssh -X運行遠程圖形化工具,並使用jvisualvm從Java二進制文件目錄加載.hprof堆轉儲文件。

該工具不會立即將完整的堆轉儲加載到內存中,而是在需要時加載部分。 當然,如果您在文件中環顧四周,所需的內存最終將達到堆轉儲的大小。

嘗試使用 jprofiler ,它在分析大型 .hprof 方面效果很好,我嘗試過使用大小約為 22 GB 的文件。

https://www.ej-technologies.com/products/jprofiler/overview.html

我遇到了一個有趣的工具,叫做 JXray。 它提供有限的評估試用許可證。 發現查找內存泄漏非常有用。 你可以試一試。

當問題可以“輕松”重現時,一種未提及的替代方法是在內存增長到那么大之前進行堆轉儲(例如<\/em>, jmap -dump:format=b,file=heap.bin <pid><\/code> )。

在許多情況下,您無需等待 OOM 即可了解正在發生的事情。

此外,MAT 提供了比較不同快照的功能,可以派上用場(有關說明和說明,請參見https:\/\/stackoverflow.com\/a\/55926302\/898154<\/a> )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM