這篇文章是我們原來的GC超出限制的問題模式帖子的延續。 正確的Java堆分析對于消除O??utOfMemoryError:GC開銷問題至關重要。 如果您不熟悉此Java HotSpot 1.6錯誤,建議您首先閱讀有關此主題的第一篇文章 。
本文將為您提供一個示例程序和一個教程,介紹如何在OutOfMemoryError之后使用Memory Analyzer分析Java HotSpot堆的占用空間。 我強烈建議您使用本教程自己執行和分析堆轉儲,以更好地理解這些原理。
故障排除工具
**所有這些工具都可以免費下載**
- Eclipse Indigo發布
- 通過IBM Support Assistant 4.1進行的內存分析器(熱點堆轉儲分析)
- Java虛擬機:Windows HotSpot JRE 1.6.0_24 64位
示例Java程序
下面的簡單Java示例程序將用于觸發OutOfMemoryError; 使我們能夠分析生成的HotSpot堆轉儲文件。 只需創建一個新的Java類:JVMOutOfMemoryErrorSimulator.java到您選擇的Eclipse項目,然后重命名或保持當前包不變。
該程序基本上是在Map數據結構內創建多個String實例,直到Java Heap耗盡為止。
**請確保您的Eclipse編譯器和JRE為1.6 **
package org.ph.javaee.javaheap;import java.util.Map;
import java.util.HashMap;/**
* JVMOutOfMemoryErrorSimulator
*
* @author PH
*
*/public class JVMOutOfMemoryErrorSimulator {private final static int NB_ITERATIONS = 500000;// ~1 KB data footprint private final static String LEAKING_DATA_PREFIX = "datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadat
adatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadat
adatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadat
adatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadat
adatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadat
adatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata";// Map used to stored our leaking String instances private static Map<String, String> leakingMap;static { leakingMap = new HashMap<String, String>(); }/** * @param args */ public static void main(String[] args) {System.out.println("JVM OutOfMemoryError Simulator 1.0"); System.out.println("Author: Pierre-Hugues Charbonneau"); System.out.println(" http ://javaeesupportpatterns.blogspot.com/");try {for (int i = 0; i < NB_ITERATIONS; i++) {String data = LEAKING_DATA_PREFIX + i;// Add data to our leaking Map data structure... leakingMap.put(data, data);}} catch (Throwable any) { if (any instanceof java.lang.OutOfMemoryError){System.out.println("OutOfMemoryError triggered! "+ any.getMessage() + " [" + any + "]");} else { System.out.println("Unexpected Exception! " + any.getMessage() + " [" + any + "]"); } }System.out.println("simulator done!"); }}
步驟#1 –設置JVM啟動參數
首先,按照以下步驟設置Eclipse Java運行時參數。 對于我們的示例,我們在Eclipse IDE外部使用了Java Jap最大容量為512 MB的外部JRE 1.6。
允許我們生成堆轉儲的主要JVM參數是-XX:+ HeapDumpOnOutOfMemoryError,它告訴JVM在OutOfMemoryError條件之后生成堆轉儲。
步驟#2 –運行示例Java程序
下一步是運行我們的Java程序。 根據您的計算機規格,此程序將在存在OutOfMemoryError之前運行5-30秒。
如您所見,JVM生成了一個堆轉儲文件java_pid3880.hprof。 現在是時候啟動“內存分析器”工具并分析JVM堆轉儲了。
步驟#3 –加載堆轉儲
分析堆轉儲是一項簡單或非常復雜的分析活動。 本教程的目的是為您提供堆轉儲分析的基礎知識。 有關堆轉儲的更多分析,請參考此博客的其他案例研究。
步驟#4 –分析堆轉儲
下面是快照和分析步驟,可用來了解我們在示例Java程序中模擬的內存泄漏。
如您所見,使用Memory Analyzer工具進行的堆轉儲分析能夠輕松識別我們主要的泄漏Java類和數據結構。
結論
我希望這個簡單的Java程序和“堆轉儲”分析教程能夠幫助您了解使用原始堆轉儲數據進行Java堆分析的基本原理。 處理OutOfMemoryError:GC開銷問題時,此分析非常重要,因為這些是Java Heap占位面積/調整問題的Java Heap泄漏的癥狀。
參考: 超出了GC開銷限制– Java EE支持模式和Java教程博客中的JCG合作伙伴 Pierre-Hugues Charbonneau進行了Java 堆分析 。
翻譯自: https://www.javacodegeeks.com/2012/05/gc-overhead-limit-exceeded-java-heap.html