Skip to main content

GC overhead limit exceeded – Java Heap analysis



GC overhead limit exceeded – Java Heap analysis
by Pierre Hugues Charbonneau on May 17th, 2012 | Filed in: Core Java Tags: Garbage Collection, JVM
This post is the continuation of our original GC overhead limit exceeded problem patterns post. Proper Java Heap analysis is critical in order to eliminate your OutOfMemoryError: GC overhead problem. If you are not familiar with this Java HotSpot 1.6 error, I recommend that you first review my First Article on this subject.
This article will provide you with a sample program and a tutorial on how to analyze your Java HotSpot Heap footprint using Memory Analyzer following an OutOfMemoryError. I highly recommend that you execute and analyse the Heap Dump yourself using this tutorial in order to better understand these principles.
Troubleshooting tools
** all these tools can be downloaded for free **
  •  Eclipse Indigo Release 
  •  Memory Analyzer via IBM Support Assistant 4.1 (HotSpot Heap Dump analysis) 
  • Java VM: Windows HotSpot JRE 1.6.0_24 64-bit
Sample Java program
The simple sample Java program below will be used to triggered an OutOfMemoryError; allowing us to analyze the generated HotSpot Heap Dump file. Simply create a new Java class : JVMOutOfMemoryErrorSimulator.java to the Eclipse project of your choice and either rename or keep the current package as is.
This program is basically creating multiple String instances within a Map data structure until the Java Heap depletion.
Description: http://1-ps.googleusercontent.com/x/www.javacodegeeks.com/3.bp.blogspot.com/-vv2x4x6yewM/T7Tj7NaEz_I/AAAAAAAAAMQ/I7XyLGo_d64/s1600/GC_overhead_Eclipse_Project.png.pagespeed.ce.K4YZFILThY.png
** please make sure your Eclipse compiler and JRE is 1.6 **
01
package org.ph.javaee.javaheap;
02


03
import java.util.Map;
04
import java.util.HashMap;

05

06
/**

07
* JVMOutOfMemoryErrorSimulator
08
*

09
* @author PH
10

11
*/public class JVMOutOfMemoryErrorSimulator {
12


13
       private final static int NB_ITERATIONS = 500000;
14


15
       // ~1 KB data footprint      
16
       private final static String LEAKING_DATA_PREFIX = "datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadat





17
adatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadat
18
adatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadat

19
adatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadat
20
adatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadat

21
adatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata";
22






23
       // Map used to stored our leaking String instances      
24
       private static Map<String, String> leakingMap;

25

26
       static {             

27
              leakingMap = new HashMap<String, String>();      
28
       }

29

30
       /**       

31
        * @param args       
32
        */      

33
        public static void main(String[] args) {
34


35
              System.out.println("JVM OutOfMemoryError Simulator 1.0");         
36
              System.out.println("Author: Pierre-Hugues Charbonneau");         

37
              System.out.println(" http ://javaeesupportpatterns.blogspot.com/");
38


39
              try {
40


41
                     for (int i = 0; i < NB_ITERATIONS; i++) {
42


43
                          String data = LEAKING_DATA_PREFIX + i;
44


45
                          // Add data to our leaking Map data structure...     
46
                          leakingMap.put(data, data);

47

48
                     }

49

50
              } catch (Throwable any) {                    

51
                     if (any instanceof java.lang.OutOfMemoryError){
52
                             System.out.println("OutOfMemoryError triggered! "

53
                                         + any.getMessage() + " [" + any + "]");
54


55
                     } else {                          
56
                           System.out.println("Unexpected Exception! " +

57
                                   any.getMessage() + " [" + any + "]");
58
                            }             

59
                     }
60


61
                     System.out.println("simulator done!");      
62
            }

63

64
}
Step #1 – Setup your JVM start-up arguments
First, setup your Eclipse Java runtime arguments as per below. For our example, we used an external JRE 1.6 outside the Eclipse IDE with a Java Heap maximum capacity of 512 MB.
The key JVM argument allowing us to generate a Heap Dump is -XX:+HeapDumpOnOutOfMemoryError which tells the JVM to generate a Heap Dump following an OutOfMemoryError condition.
Description: http://1-ps.googleusercontent.com/x/www.javacodegeeks.com/2.bp.blogspot.com/-t7pF-WPKqao/T7TkPQBmtSI/AAAAAAAAAMY/oxVGmKmlAx8/s1600/GC_overhead_Run_Configuration.png.pagespeed.ce.9S9fsiX8t_.png
Description: http://1-ps.googleusercontent.com/x/www.javacodegeeks.com/3.bp.blogspot.com/-T5VoaDboPSA/T7TkdKtVt3I/AAAAAAAAAMg/xDUqFFYQGEA/s1600/GC_overhead_Run_Configuration_JVM.png.pagespeed.ce._yTZSYr-Je.png
Step #2 – Run the sample Java program
The next step is to run our Java program. Depending on your computer specs, this program will run between 5-30 seconds before existing with an OutOfMemoryError.
Description: http://1-ps.googleusercontent.com/x/www.javacodegeeks.com/4.bp.blogspot.com/-TyVHzcKZNvM/T7TkphKAYoI/AAAAAAAAAMo/Fzqm-xp_GG0/s1600/GC_overhead_Run_Java_Program_Exec.png.pagespeed.ce.AxmODXOH8v.png
As you can see, the JVM generated a Heap Dump file java_pid3880.hprof . It is now time to fire the Memory Analyzer tool and analyze the JVM Heap Dump.

Step #3 – Load the Heap Dump
Analyzing a Heap Dump is an analysis activity that can be simple or very complex. The goal of this tutorial is to give you the basics of Heap Dump analysis. For more Heap Dump analysis, please refer to the other case studies of this Blog.
Description: http://1-ps.googleusercontent.com/x/www.javacodegeeks.com/2.bp.blogspot.com/-ORS081MkJ_w/T7Tk4PP9vTI/AAAAAAAAAMw/EWfJgb3t2dM/s1600/GC_overhead_Heap_Dump_analysis1.png.pagespeed.ce.FtAt2mQNs-.png
Description: http://1-ps.googleusercontent.com/x/www.javacodegeeks.com/4.bp.blogspot.com/-0w-KMvSGXeo/T7Tk_hcsWaI/AAAAAAAAAM4/R9VFQfcqhDc/s1600/xGC_overhead_Heap_Dump_analysis2.png.pagespeed.ic.85uV9WWo1B.png
Description: http://1-ps.googleusercontent.com/x/www.javacodegeeks.com/2.bp.blogspot.com/-0IcLgt1Hdrc/T7TlGuiqd1I/AAAAAAAAANA/_q8N_xj3vCE/s1600/GC_overhead_Heap_Dump_analysis3.png.pagespeed.ce.-ZWJ0_XH-V.png
Step #4 – Analyze Heap Dump
Below are the snapshots and analysis steps that you can follow to understand the memory leak that we simulated in our sample Java program.
Description: http://1-ps.googleusercontent.com/x/www.javacodegeeks.com/4.bp.blogspot.com/-LLbGEhEQ7NI/T7TlTWDB3gI/AAAAAAAAANI/jKERcI9P86A/s1600/GC_overhead_Heap_Dump_analysis4.png.pagespeed.ce.8flFwAkk2s.png
Description: http://1-ps.googleusercontent.com/x/www.javacodegeeks.com/1.bp.blogspot.com/-QAlFDi9yUSE/T7TlbGsV0jI/AAAAAAAAANQ/Hi3-5kvaSVA/s1600/GC_overhead_Heap_Dump_analysis5.png.pagespeed.ce.4XeQaLmMM_.png
Description: http://1-ps.googleusercontent.com/x/www.javacodegeeks.com/4.bp.blogspot.com/-hmT4itSYxeY/T7TlyxIJFyI/AAAAAAAAANY/-x3j7GiI-Dk/s1600/GC_overhead_Heap_Dump_analysis6.png.pagespeed.ce.TDmM4aEtFb.png
Description: http://1-ps.googleusercontent.com/x/www.javacodegeeks.com/1.bp.blogspot.com/-CFTykvClFAw/T7TmCxuc9WI/AAAAAAAAANg/ZnThp2WY7XY/s1600/GC_overhead_Heap_Dump_analysis7.png.pagespeed.ce.eyas59tWhd.png
As you can see, the Heap Dump analysis using the Memory Analyzer tool was able to easily identify our primary leaking Java class and data structure.
Conclusion
I hope this simple Java program and Heap Dump analysis tutorial has helped you understand the basic principles of Java Heap analysis using the raw Heap Dump data. This analysis is critical when dealing with OutOfMemoryError: GC overhead problems since those are symptoms of either Java Heap leak of Java Heap footprint / tuning problem.

Comments

Popular posts from this blog

Custom camera using SurfaceView android with autofocus & auto lights & more

Custom camera using SurfaceView android with autofocus & auto lights & much more /**  * @author Tatyabhau Chavan  *  */ public class Preview extends SurfaceView implements SurfaceHolder.Callback {     private SurfaceHolder mHolder;     private Camera mCamera;     public Camera.Parameters mParameters;     private byte[] mBuffer;     private Activity mActivity;     // this constructor used when requested as an XML resource     public Preview(Context context, AttributeSet attrs) {         super(context, attrs);         init();     }     public Preview(Context context) {         super(context);         init();     }     public Camera getCamera() {         return this.mCamera;     }     public void init() {         // Install a SurfaceHolder.Callback so we get notified when the         // underlying surface is created and destroyed.         mHolder = getHolder();         mHolder.addCallback(this);         mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);     }     public

Get Android phone call history/log programmatically

Get Android phone call history/log programmatically To get call history programmatically first add read conact permission in Manifest file : <uses-permission android:name="android.permission.READ_CONTACTS" /> Create xml file. Add the below code in xml file : <Linearlayout android:layout_height="fill_parent"  android:layout_width="fill_parent" android:orientation="vertical"> <Textview android:id="@+id/call" android:layout_height="fill_parent" android:layout_width="fill_parent"> </Textview> </Linearlayout> Now call the getCallDetails() method in java class : private void getCallDetails() { StringBuffer sb = new StringBuffer(); Cursor managedCursor = managedQuery( CallLog.Calls.CONTENT_URI,null, null,null, null); int number = managedCursor.getColumnIndex( CallLog.Calls.NUMBER ); int type = managedCursor.getColumnIndex( CallLog.Calls.TYPE ); int date = managedCur

Bitmap scalling and cropping from center

How to Bitmap scalling and cropping from center? public class ScalingUtilities {     /**      * Utility function for decoding an image resource. The decoded bitmap will      * be optimized for further scaling to the requested destination dimensions      * and scaling logic.      *      * @param res      *            The resources object containing the image data      * @param resId      *            The resource id of the image data      * @param dstWidth      *            Width of destination area      * @param dstHeight      *            Height of destination area      * @param scalingLogic      *            Logic to use to avoid image stretching      * @return Decoded bitmap      */     public static Bitmap decodeResource(Resources res, int resId, int dstWidth,             int dstHeight, ScalingLogic scalingLogic) {         Options options = new Options();         options.inJustDecodeBounds = true;         BitmapFactory.decodeResource(res, resId, options);