Arch2Arch Tab BEA.com
Syndicate this blog (XML)

How fragmented is my Java heap?

Bookmark Blog Post

del.icio.us del.icio.us
Digg Digg
DZone DZone
Furl Furl
Reddit Reddit

Henrik Stahl's Blog | December 11, 2007   2:06 AM | Comments (7)


One major cause for long GC pause times is heap fragmentation. How problematic this for an application depends on its allocation pattern. The worst possible case is an application that allocates a mix of objects with very different sizes and lifetimes. After the application has been running for a while, the Java heap will be fragmented by lots of long lived Java objects spread out across the heap. There may be plenty of free space available, but no large block of contiguous free memory. When the application then attempts to allocate a large object such as an array, it is unable to find room to store it. The result will be a long GC pause while the heap is compacted.

If you suspect you have this issue with your application, the first step is to try to find out exactly how fragmented the heap is. One simple way of doing this is by using the JRockit Runtime Analyzer. Here's an example:

1. Start a Java application on your workstation
2. Start up JRockit Mission Control using the Start menu icon in Windows or the $JR_HOME/bin/jrmc executable
3. Locate the process you want to analyze, right-click and select to start a JRA recording.

start-jra.PNG

4. Select recording time (here 2 minutes) and start the recording

jra-wizard.PNG

5. After the recording has finished, it will be opened in the JRMC GUI. Select the Heap tab. Heap fragmentation is displayed in black in the Heap Contents pie chart.

jra-heap.PNG

The application in this example is well behaved and shows only 11% fragmentation - well within acceptable limits. I would start getting concerned if it went above 30%, and more if it continued to increase. Another warning sign is if the free memory distribution (pie chart on the right) contains a very large proportion of smaller free blocks.

If you found this useful, let me know and I'll write an entry on how to deal with heap fragmentation.


Comments

Comments are listed in date ascending order (oldest first) | Post Comment

  • I certainly found it, but you already know it. Would be interested on that heap fragmentation post. My bet is to fine tune compaction times and to set up proper TLA sizes to fit your needs but I would look forward to see your article. Martin

    Posted by: churrusco on December 11, 2007 at 7:12 AM

  • We came across the problem of high fragmentation and were frustrated when we could not find anything on the net to help us. I would like to share the solution to this problem. Our application runs on jrockit 64-bit with a 6 GB heap. It is a soft real-time application running hundreds of transactions per second.

    Having a deadly mix of short-lived, long-lived, small and large objects scattered across the heap (as described above), the application would run well for about 12 hours. However, due to a bug in jrockit R27.3.1's compaction algorithm, it would suddenly stop compacting. Neither the internal nor external compaction would work. (Note that the external compaction would continue to scan the heap but never compact anything). After time, CPU usage would increase, threads would wait in excess of 10 seconds for memory allocation and the compaction algorithm would kick in for "exceptional" compaction only. This would only de-fragment a minimal amount of heap to meet immediate needs all the while leaving the heap highly fragmented. In some cases, a long 20-second pause would kick in and de-fragment the entire heap. This was non-deterministic as we've also seen cases where 5 minute pauses would occur with no compaction. In short, high fragmentation resulted in bad performance.

    The problem was solved with a BEA patch on R27.3.1 as well as with compaction tuning parameters. We set the internal and external compact ratios to 5 and the heap parts to 4096. This, along with the jrockit patch, allowed the compaction to work on 5 parts of 4096 heap parts at a time allowing a smooth compaction amortized throughout the day. The end result is that the dark matter now hovers at around 300Mb instead of 1.5 GB. Also, compaction pauses and GC pauses with gencon are low and CPU usage were cut in half.

    Posted by: Nick Maiorano on December 11, 2007 at 7:29 AM

  • could you please post the CR-id of the "compaction patch" for jrockit R27.3.1? thanks in advance, m.

    Posted by: makiey on January 15, 2008 at 3:02 AM

  • I don't know which issue Nick refers to, but here's what I could glean from the Support database:

    • CR354392 - Compactions aborted due to counters not resetted between GCs (fixed in R27.5)
    • CR314527 - Compaction causing long pause times when trying to move a large object from the top of the heap (fixed in R27.3)

    Posted by: hstahl on January 15, 2008 at 4:36 AM

  • thanks, already talked to support, looks like we should keep an eye on 354392/351185. regards, makiey

    Posted by: makiey on February 8, 2008 at 1:44 AM

  • Can you guide me as to how to connect to a standalone java program?

    Posted by: jeeva2 on February 21, 2008 at 1:01 PM

  • The JRMC GUI will automatically detect and enable connections to an Java programs running with JRockit on the local machine in the same user session. Remote connection is also simple. Start your Java program with JRockit and -Xmanagement:ssl=false,authentication=false,port=7091,autodiscovery=true and all JRMC GUIs on the same network will automatically detect and enable connections. See the JRockit reference manual entry on -Xmanagement on e-docs.bea.com for more detail.

    Posted by: hstahl on February 22, 2008 at 12:21 AM



Only logged in users may post comments. Login Here.

Powered by
Movable Type 3.31