Javolution creator Jean-Marie Dautelle discusses different methods to reduce the worst-case execution time of Java applications by leveraging the extra processing power of multicore systems. The methods described here do not require specialized real-time virtual machines and are suitable for many types of applications for which unexpected delays in the tens or hundreds of milliseconds are not acceptable.
Real-time response is a requirement in Java application domains such as banking, online collaboration, and games development, as well as for safety critical applications used in hospitals, manufacturing, aviation, and emergency response systems. Unfortunately, the Java platform has long suffered from its erratic response time. Java applications are known to freeze because the garbage collector has "stopped the world." Incremental garbage collection (
-Xincgc) improves this situation, but it does not completely eliminated the nasty "full GC" pauses associated with the Java platform.
To further complicate things, Java program execution also can suffer from unexpected delays caused by Just-In-Time (JIT) compilation, class initialization, or standard utility collections internally resizing.
This dire situation has led to the development of proprietary real-time virtual machines such as IBM WebSphere Real Time and Sun Mackinac. It also led me to create the real-time Javolution library. While real-time virtual machines are quite expensive, the Javolution library is free. As you'll learn in this article, it is also possible to exploit multicore processing power to increase real-time application responsiveness and reduce unexpected delays.
Our real-time benchmark
In order to measure the effects of the real-time solutions discussed in this article, I will run a simple program calculating a FFT (Fast Fourier Transform). The test program, rt-test1.java, uses complex numbers that have to be allocated and garbage collected. I'll first show what I can do to improve this program's benchmarks by optimizing the Java HotSpot virtual machine for real time GC and compilation. In rt-test2.java I'll rewrite the program using specialized classes from my Javolution library. The goal in both cases is to minimize the worst-case execution time. If you would like to run your own tests, you may substitute any code generating many temporary objects.
I first run the benchmark on an Intel Core Duo Laptop 2GHz, Java 1.6 with the following runtime arguments (for 256 MB fixed-size memory):
The resulting execution time and memory usage are shown in Figure 1.
Figure 2 shows the memory usage for this benchmark. As you can see, "full GC" took place and lasted almost one full second!