Realistically real-time

Real-time Java application development using multicore systems

Page 2 of 4

Concurrent, low pause collector

In November 2006, Sun released the source code for the Java HotSpot virtual machine under the GPL v2 and initiated the OpenJDK project.

The generational collector used by HotSpot is very efficient for collecting short-lived objects and can be tuned to collect young generation (objects created since the last incremental garbage collection) quickly. For example, the setting -XX:NewRatio=3 means that the ratio between the young and tenured generation is 1:3.

The larger the ratio, the shorter the minor collection time, but (unfortunately) the more frequent the major collections have to be! Java SE 6 HotSpot has some advanced options for working around this problem. Two of these are of particular interest to us:

-XX:+UseConcMarkSweepGC
-XX:+CMSIncrementalMode

This first option activates the concurrent mark sweep (CMS) collector (also known as the concurrent low pause collector). This collector attempts to minimize the pauses due to garbage collection by doing most of the garbage collection work concurrently with the application threads. In other words, the VM can take advantage of idle cores to perform garbage collection concurrently. It should be noted that this option is different from -XX:+UseParallelGC, which uses multiple threads for collection and only executes the collector faster. (Furthermore, the parallel collector cannot be used with the concurrent low pause collector.)

The second option allows CMS to run even if you are not reaching the limits of memory. It prevents CMS from kicking in too late and being unable to finish its collection before available memory is exhausted. Figure 3 is the execution graph of our real-time benchmark with the CMS options activated.

Benchmark with HotSpot CMS options activated.
Figure 3. Benchmark with HotSpot CMS options activated: Maximum execution time: 56.689048 ms Average execution time: 19.683719 ms

Figure 4 shows the memory usage for this test.

HotSpot memory usage with concurrent mark sweep.
Figure 4. HotSpot memory usage with concurrent mark sweep

As you see, the worst-case execution time has been reduced by an order of magnitude, but the average execution time has increased.

Ahead-of-time compilation and alternatives

HotSpot does not provide an option to compile classes before execution. It does provide an option to specify the compilation threshold (the number of times a method has to be executed before being compiled). Setting the compilation threshold to one (-XX:CompileThreshold=1) forces the code to be compiled at first execution. This option is not as good as ahead-of-time compilation (supported by virtual machines such as Excelsior JET) or static native compilation (supported by the Gnu Compiler for Java) due to the performance hit the first time the code is executed. But it is often possible to execute critical code at startup and prevent JIT compilation from occurring at an inappropriate time. Figure 5 shows the benchmark result from using this option in conjunction with the CMS collector.

Benchmark with CompileThreshold=1.
Figure 5. Benchmark with CompileThreshold 1: Maximum execution time: 49.830635 ms Average execution time: 19.737168 ms

Because the benchmark code is so small, compiling the code at start-up does not result in a significant reduction in the worst-case execution time. However, JIT compilation for large applications may delay code execution by hundreds of milliseconds.

| 1 2 3 4 Page 2