Sun and HP-UX generational collectors

The Sun and HP JVM organized its heap into generations to improve the efficiency of its garbage collection, and to reduce the frequency and duration of user-perceivable garbage collection pauses. The premise behind generational collection is that memory is managed in generations or in pools of memory with different ages (see Figure 1).

Figure 1. Heap layout

New objects are allocated in the eden. When the eden fills up, the JVM issues a scavenge GC or minor collection to move the surviving objects into one of the two survivor or semi spaces. The JVM does this by first identifying and moving all referenced objects in the eden to one of the survivor space. At the end of the scavenge GC, the eden is empty (since all the referenced objects are now in the survivor space) and ready for object allocation.

The scavenge GC's efficiency depends on the amount of referenced objects it has to move to the survivor space and not on the size of the eden. The higher the amount of referenced objects, the slower the scavenge GC. Studies, however, have shown that most Java™ objects live a very short time. Since most objects live for a short time, one can typically create large edens.

Referenced objects in the survivor space bounce between the two survivor spaces at each scavenge GC until it either becomes unreferenced or the number of bounces has reached the tenuring threshold. If the tenuring threshold is reached, that object is migrated up to the old heap.

When the old heap fills up, the JVM issues a Full GC or major collection. In a Full GC, the JVM has to first identify all the referenced objects. When that is done, the JVM sweeps the entire heap to reclaim all free memory (for example, because the object is now dead). Finally, the JVM then moves referenced objects in order to defragment the old heap. The efficiency of the Full GC is dependent on the amount of referenced objects and the size of the heap. For more information see The Java HotSpot Performance Engine Architecture (http://www.oracle.com/technetwork/java/whitepaper-135217.html),and extensive Java SE Hotspot information on http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136373.html.

Heap settings

It is both a curse and a blessing that the SunSoft based JVMs provide many parameters to control the JVM heap configuration. Tuning the SunSoft generational collectors can be part art and part guess work. You may opt for the Keep It Simple Strategy Principle. In the following example, only specify the starting (-Xms) and maximum (-Xmx) heap size:

   java -server -Xms358m -Xmx358m weblogic.Server
   

When choosing the JVM settings, you should keep the following in mind:

When setting the young heap, keep the following recommendations in mind:

Keep in mind the following when configuring the survivor spaces:

Keep in mind the following when configuring the old heap:

Therefore, you should allocate the old heap large enough so that Full GCs are not occurring too frequently (e.g., more than once in 15 minutes) and the collection service time is less than 2 seconds

Young generation guarantee

Note: Young Generation Guarantee is valid only for serial collector from JDK 1.5 (and later).
Starting in JDK 1.3.1_05, the Sun/HP JDKs implemented a conservative garbage collection policy called the Young Generation Guarantee. Before starting a GC, the JVM checks if the free space in the old heap (OLD FREE) is larger than the sum of the eden. The premise is that it is possible (though highly unlikely) that every object in the eden (remains alive and uncollected) the collection and has to be promoted to the old heap. If that ever happens, the Young Generation Guarantee ensures that there is enough free space in the old heap for all the promoted objects.

Starting recommendations

We recommend that you try the default generational settings with a 384M and a 768M heap for your agents and application servers respectively:

   java -server -Xms768m -Xmx768m \
        -XX:MaxPermSize=256m \
        weblogic.Server
   

Another approach is to set the overall heap to 1024MB with a 200MB young generation. For Solaris, you would issue the following command:

   java -server -Xms1024m -Xmx1024m \
        -XX:NewSize=200m -XX:MaxNewSize=200m \
        -XX:MaxPermSize=256m \
        weblogic.Server
   

For HP-UX, you would issue the following command:

   java -server -Xms1024m -Xmx1024m \
        -Xmn200m \
        -XX:MaxPermSize=256m \
        weblogic.Server
   

You have to regularly monitor the "health" of the garbage collection and adjust accordingly. For example:

The optimum JVM heap setting depends on your workload characteristics, your workload concurrency levels, your workload complexity, and so forth. The JVM heap setting can be (and often is) different between the application servers and agents. In addition, the settings may be different between some agents. As a result, you must periodically check the effectiveness of each JVM's heap setting.

Garbage collection statistics

We recommend that you continuously collect garbage collection statistics for all JVMs even in production. The collection overhead is minor compared to the benefit. With the statistics, you can tell if:

For a Sun JVM, the following statistics are displayed if you enable -XX:+PrintGCDetails, -XX:+PrintGCTimeStamps, and -Xloggc:file:

   0.000: [GC 0.001: [DefNew: 32192K->511K(33152K), 0.0383176 secs]
32192K->511K(101440K), 0.0385223 secs]
   1.109: [GC 1.110: [DefNew: 32703K->198K(33152K), 0.0344874 secs]
32703K->697K(101440K), 0.0346844 secs]
   

For an HP JVM, the following statistics are shown if you enable -Xverbosegc:file:

   <GC: 1 0 13848.360276 8 16400 31 429520056 0 429522944 0 2328104 53673984
100687544 100687544 536870912 69787968 69787968 69992448 0.162748 >
   <GC: 1 0 73541.610471 9 48 31 429522944 0 429522944 2328104 9051392 53673984
100687544 100687544 536870912 70708000 70708000 70778880 0.249739 >
   
   

To ensure the previous file is not overwritten after a restart, parameterize the "file" in -Xloggc:file and -Xverbosegc:file.

Note: Create the GC log file name with the name of the workload and the starting time. In the example below the -XX:+PrintGCTimeStamps directive provides relative times of the GC from the time the JVMs started for the WebLogic server. The starting time in the file name allows you to determine when the GCs occurred:
   WORKLOAD=SCHEDULE
   gclog_file=${WORKLOAD}_‘date +%Y%m%d-%H%M%S‘
   java -verbosegc -XX:+PrintGCTimeStamps -Xloggc:${gclog_file}
weblogic.Server
If you want the GC logs for Sun JVM to include date information, use the "-XX:+PrintGCDateStamps Java argument. IBM® JDK provides the date/time information, by default.
Note: For Windows, format the example appropriately.