Java Performance Tuning

Java(TM) - see bottom of page

|home |services |training |newsletter |tuning tips |tool reports |articles |resources |about us |site map |contact us |
Tools: | GC log analysers| Multi-tenancy tools| Books| SizeOf| Thread analysers| Heap dump analysers|

Our valued sponsors who help make this site possible
JProfiler: Get rid of your performance problems and memory leaks! 

Training online: Concurrency, Threading, GC, Advanced Java and more ... 

Tool Report: GCViewer

Get rid of your performance problems and memory leaks!

Modern Garbage Collection Tuning
Shows tuning flow chart for GC tuning

Java Performance Training Courses
COURSES AVAILABLE NOW. We can provide training courses to handle all your Java performance needs

Java Performance Tuning, 2nd ed
The classic and most comprehensive book on tuning Java

Java Performance Tuning Newsletter
Your source of Java performance news. Subscribe now!
Enter email:

Training online
Threading Essentials course

Get rid of your performance problems and memory leaks!

Published July 2002

The Tool Reports are designed to help readers make informed choices about the tools they may wish to use. provides these reports as a service to our readers; is not responsible for the information provided by the tool author or vendor, nor do we necessarily endorse the products mentioned. is not responsible for any additional resources provided from the article (such as downloadable files or other accessible material), even where we host such material.


GCViewer is a little tool that visualizes verbose garbage collection data generated by Sun and IBM Java Virtual Machines (JVM). The analysis of this data can be useful for tuning applications in order to maximize the performance of the garbage collector and thus the application itself.

Supported verbose:gc formats are:

  • Sun JDK 1.4 with the option -Xloggc:<file> (preferred)
  • Sun JDK 1.3.1/1.4 with the option -verbose:gc
  • IBM JDK 1.3.0 with the option -verbose:gc
  • IBM JDK 1.2.2 with the option -verbose:gc
  • Installation

    To install GCViewer simply download the latest version from Put the archive into the directory where you want to install GCViewer and unpack it. Then change into the newly created directory gcviewer-XXX. On Windows systems, where JAR files are associated with the java launcher, you can simply double click on the file gcviewer.jar to start the application. In all other cases, you can start GCViewer like this:

    java -jar gcviewer.jar


    Once you have started GCViewer you will see a Swing window. The figure below depicts most of the available controls with a short description.

    GUI Overview

    By using the View-menu you may turn particular lines on or off. ("Acc Pauses" is the accumulated pause time from garbage collections.)


    Mostly it's server applications that benefit from tuning garbage collection. Therefore we want to look at a very simple (somewhat artificial) example of a serverside application. In our setup the webserver jo! is pounded by Apache JMeter for a limited time. To keep this example as simple as possible, the same resource is requested again and again.

    Obtaining GC data

    In order to obtain garbage collection data, jo! is started with Sun JDK 1.4.0 Server and the following parameters:

    c:\j2sdk1.4.0\bin\java -server -Xloggc:normal.gc ... (off course this works under Unix/Linux, too)

    The parameter -Xloggc:normal.gc tells the VM that it should write verbose garbage collection information to the file normal.gc. After our test run finished we open the file with GCViewer:

    GC Data with normal garbage collection - 200%

    Probably the two most important lines in the graph are the red and the blue line. The red line indicates the total heap size, the blue line shows how much of the heap is actually used. As we can see the blue line follows a saw like pattern. If we increase the zoom to 1.000% it becomes obvious that this pattern is repeated in each tooth of the saw.

    GC Data with normal garbage collection - 1.000%

    To understand why we see this doubled saw pattern, we have to take a look at the garbage collector being used.

    Sun JDK 1.4.0 Server uses a generational garbage collector with two young generations and an old generation. New objects are always allocated in the young generation part of the heap. Every time the young generation is full a minor garbage collection takes place. In the graph this is indicated by the little grey lines at the bottom. As you can see from the length of these lines (and the green line), minor garbage collections don't take very long. Objects which survived some minor collections are promoted to the older generation. Usually the older generation is full at some point too, and needs to be cleaned. This leads to a major garbage collection that removes garbage from both the old and the younger generations. Full garbage collections are indicated by black vertical lines. As you can see in the graph (green line), full garbage collections take a lot longer than minor garbage collections. This is due to the fact that a larger part of the memory is cleaned and that the older generation uses a slower, but less memory consuming, garbage collection algorithm than the younger generation.

    To summarize this: The saw pattern in the first figure (zoom 200%) shows full garbage collections, the saw pattern in the second figure (zoom 1 000%) shows minor garbage collections.

    Enlarging the new generation

    How can this help us tune the application? Well, after each minor collection the heap memory consumption is slightly higher than after the minor collection before. Some objects have been promoted to the older generation. But every time a full collection occurs the memory consumption (blue line) is reduced to more or less the same value as after the last full collection. This means that even though some objects were promoted to the older generation, most of them didn't become very old either. Which means, that maybe they should not have been promoted to the older generation in the first place.

    In this particular scenario it seems beneficial to increase the size of the younger generation to prevent the early promotion of medium-lived objects. For Sun JDK 1.4.0/1.3.1 this can be achieved with the unsupported parameter -XX:NewRatio=<value>. This parameter defines the ratio between the young and the old generations. A NewRatio of 2 means, that the young generations use one third of the heap. The default value of this parameter differs depending on your VM, whether you use the Server HotSpot compiler or the Client HotSpot compiler and which platform you are operating on.

    To see what effect a different NewRatio has on our application we start it like this:

    c:\j2sdk1.4.0\bin\java -server -XX:NewRatio=2 -Xloggc:newratio2.gc ...

    The figure below shows the result:

    GC Data with NewRatio=2 - 200%

    It is obvious that fewer full garbage collections occur (4 instead of 9) and that the minor collections remove more garbage (1 Mbyte instead of 0.5 MByte). Because fewer full garbage collections took place the accumulated pause time (Acc Pauses) caused by garbage collections decreased from 4.26s to 2.26s. This means that the application now spends only little more than half as much time on garbage collection than before. This sounds great, but to be honest for this application the overall effect of this improvement isn't terribly large as we didn't have excessive pause times in the first place. But still, the throughput (time the application actually runs and isn't busy with garbage collection) increased from 97.62% to 98.84%. Again - if your real world application has a throughput of over 95% you probably shouldn't bother with tuning garbage collection.

    As a side effect of NewRatio=2 we notice that the overall memory consumption (Footprint) slightly increased from 3.364 KByte to 3.604 KByte. This is due to the larger younger generation.

    Tweaking it even more

    To see whether we can improve the throughput even more, we start another test run with NewRatio=1:

    GC Data with NewRatio=1 - 200%

    As you can see from the graph there are still four full collections - but they occur in the initialization and shutdown phases of the test run. Also, they don't seem to take a very long time. The sum of all pause times decreased from 2.26s to 1.74s and as a direct result the throughput increased to fantastic 99.02%. The downside of this improvement is the increased footprint of 4.756 KByte.

    Tuning real applications

    In our example we used a very simple scenario to demonstrate a single tuning effort. In a real application we would have to make sure that we can repeat test runs in order to compare the values. For the sake of repeatability and not hindering the everyday business you should set up a test environment that is identical to your production environment and run load tests that simulate real load situations. You should also measure the performance of your application without verbose garbage collection in order to measure the real effect of any garbage collection tuning.


    GCViewer helps you interpret verbose GC data from your VM. Especially with Sun JVMs, manipulating generation sizes can have a large impact on the behaviour of your application. GCViewer helps you make the correct decisions and run the right tests. Off course this doesn't free you from the task of not producing too much garbage in the first place...

    Further Reading

  • Tuning Garbage Collection:
  • Richard Jones, Rafael Lins: Garbage Collection: Algorithms for Automatic Dynamic Memory Management. New York: Wiley & Sons 1996.
  • Author

    Hendrik Schreiber is author of the German book Performant Java Programmieren published by Addison-Wesley and works as senior consultant for innoQ Deutschland GmbH (see also iQgen). In his spare time he contributes to open source projects such as tagtraum industries and others.

    Last Updated: 2022-07-29
    Copyright © 2000-2022 All Rights Reserved.
    All trademarks and registered trademarks appearing on are the property of their respective owners.
    Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
    RSS Feed:
    Trouble with this page? Please contact us