8 Tuning for Stable Performance

This chapter describes how to tune the JVM for stable performance.

An incorrectly tuned JVM might perform well initially, but could start showing lower performance or longer latencies over time or display severe performance variations.

This chapter includes the following topics:

8.1 Measuring the Performance Variance

To measure and analyze performance variance over time you need a long-running test that continuously reports the current performance. The test scenario should be as realistic as possible and cover as many use cases as possible.

When you have identified a variance in performance you can start monitoring the Oracle JRockit JVM to check whether the variance correlates to events within the JVM (for example, garbage collection, fragmentation, or lock deflation). The tools in Oracle JRockit Mission Control and the verbose outputs generated when you use the -Xverbose option help you analyze the variance.

Table 8-1 lists the events to look for and the tools to detect and analyze each event.

Table 8-1 JVM Events

Event Type What to Look For Tools for Analysis

Heap size change

The heap increases or decreases

-Xverbose:memdbg, JRockit Flight Recorder, Oracle JRockit Mission Control

Nursery size change

The nursery size increases or decreases

-Xverbose:memdbg, JRockit Flight Recorder, Oracle JRockit Mission Control

Garbage collector strategy change

A dynamic garbage collection mode changes the garbage collection strategy

-Xverbose:memdbg, JRockit Flight Recorder

Increased fragmentation

The amount of dark matter increases

JRockit Flight Recorder

Full compaction

Compaction of all heap parts at once

-Xverbose:memdbg, JRockit Flight Recorder


8.2 Tuning the Heap Size

Heap size changes at run time can cause performance variations. You can monitor the heap size in -Xverbose:memdbg outputs and in JRockit Mission Control tools. A JRockit Flight Recorder recording also indicates whether the heap size changed during the recording.

For an even performance over time, you should set the initial heap size (-Xms) to the same value as the maximum heap size (-Xmx).

Example:

java -Xms:1g -Xmx:1g myApplication 

For more information about tuning the heap size, see Section 4.1.1, "Setting the Heap Size."

8.3 Manually Tuning the Nursery Size

Nursery size changes at run time can cause performance variations, but can also help keeping the performance high when the load changes. You can monitor the nursery size in -Xverbose:memdbg outputs and JRockit Mission Control tools. A Flight Recorder recording also indicates whether the nursery size changed during the recording.

If you find that performance variations in your application correlate to nursery size changes, you can set a static nursery size by using the -Xns option.

Example:

java -Xns:100m myApplication

For more information about tuning the nursery size, see Section 4.1.2, "Setting the Nursery and Keep Area Size."

Note:

Overriding the dynamic nursery sizing heuristics can have a negative impact on the performance or cause performance variations in applications where the amount of live data varies during the run.

8.4 Tuning the Garbage Collector

The garbage collection modes in the JRockit JVM select a garbage collection strategy based on run-time information. Changes in application behavior can cause the garbage collection mode to change. If such changes happen often and cause performance variations, you might want to select a different garbage collection mode. You can change the garbage collection mode by using the -Xgc:mode option.

Example:

java -Xgc:genpar myApplication 

For more information, see Section 4.2.1, "Selecting a Garbage Collection Mode."

8.5 Tuning Compaction

The Oracle JRockit JVM uses the mark-and-sweep garbage collection model (for more information, see the "Mark-and-Sweep Model" section in Oracle JRockit Introduction to the JDK).

This mark-and-sweep garbage collection model could cause the heap to become fragmented, which means that the free areas on the heap increase in number but become small. The JVM performs partial compaction of the heap at each garbage collection to reduce the fragmentation. Sometimes, the amount of compaction is not enough. This leads to increasing fragmentation, which, in turn, leads to more and more frequent garbage collections until the heap is so fragmented that a full compaction is performed. After the full compaction, the garbage collection frequency decreases, but gradually increases as the fragmentation increases again.

This behavior causes the performance of the Java application to vary. As the garbage collection frequency increases, the performance drops. During the full compaction, you might experience a prolonged garbage collection pause, which pauses the entire Java application for a while. After this, the performance is high again, but starts going down as the garbage collection frequency increases again.

You can monitor the compaction ratio and garbage collection frequency in -Xverbose:memdbg outputs, the Management Console, and Flight Recorder recordings. A Flight Recorder recording also shows you how much dark matter (severe fragmentation) exists on the heap. If you find that the garbage collection keeps increasing until a full compaction is done, you need to increase the compaction ratio. For information about how to tune compaction, see Section 4.3, "Tuning Compaction."

You can also decrease the fragmentation on the heap by using a generational garbage collector. For more information, see Section 4.2, "Selecting and Tuning a Garbage Collector."