This article is the first of a 2 parts serial. We will try to evaluate suitablity of Real-Time Java for your applications and how you should adapt it with minimum effort. Depending on a lot of factors, adaptation of real-time java can be very easy, especially your application does not have microseconds level of latency. Other than technical problems you may have to tackle social problems. Some of them come from C/C++ developers who perceive you as a threat to their career. The most interesting criticism I have received was, “Real-time Java is not Java!” Since you may receive the same criticism, you should prepare your answer; “An RTSJ compliant implementation should pass all compatibility tests of Java SE”. So you can be sure that Real-time Java is Java and a bit more of it. Above criticism is made because RTSJ contains a lot of new APIs and mentions concepts a normal Java developer do not deal with. For example thread priorities and memory management. Especially javax.realtime.NonHeapRealTimeThread and existence of different memory regions adds a fair amount of complexity. But not all applications need all features of RTSJ. Adaptations of real-time java should be an incremental one.
You should evaluate your real-time requirements, your target hardware and operating system. Real-time Java will simplify your development and maintenance effort when compared to C/C++, but it will not be free. You have to trade some CPU and memory for this. If you look at Sun’s real-time implementation you will see its minimum hardware requirement is:
- Dual core or dual CPU System
- 512 Mbytes of RAM
So an RTSJ compliant implementation is not suitable for low-end hardware or systems in which CPU and memory costs are a significant percentage of total cost. For this kind of low end systems there are real-time java implementations but they are not real-time java specification compliant. For example Aonix has Perc Pico and Perc Raven products that are suitable for this kind of resource constrained systems.
If you pass above initial evaluation, I recommend you to investigate real-time requirements of your application further. Is it a hard real-time system or soft real-time system? If it is only a soft real-time system with high tolerance you may decide to stay with Java SE and tune garbage collector accordingly. Although garbage collection is not the only source of indeterminism, it has the greatest share. This solution will save you RTSJ licenses. You may try following alternatives:
-
G1 (GarbageFirst) Collector:
You may try follow New G1(Garbaga First) collector in Sun’s Java 6 is low-pause, low-latency soft real-time garbage collector. Much of its processing can be controlled through command line. For example; -XX:MaxGCPauseMillis=100 -XX:GCPauseIntervalMillis=1000 will try to achieve maximum pause time of 100ms within each 1000ms interval for application threads. Although it will try its best to achieve this goal it may cause longer pause times.
-
Old Serial Collector:
It is the most simple collector shipping with Sun’s JavaSE implementation. It stops all applications threads while performing collection. Depending on other factor, like processor speed, If your heap size is very small, this collector may be suitable.
-
Old CMS (Concurrent Mark Sweep) Collector:
This collector performs most of its work concurrently with application threads. Although it is not as good as G1 collector, depending on the other factors this collector is fairly good at keeping pause time of applications threads under 1 seconds. One drawback of this collector is it may cause memory fragmentation because it is not a compacting collector.
Garbage collection performance depends on dependent on the size of the heap, the amount of live data maintained by the application and the number and speed of available processors. Every application is different and you should invest some effort to tune garbage collector to increase throughput and reduce pause times. Unfortunately you generally have to trade throughput for low latency, not only in garbage collection, but also in most other areas of RT.
Not: All garbage collectors are seriously effected if your heap is swapped to disk by operating system. For this reason you should pin application’s memory pages to RAM and should use large memory pages for saving TLB (Translation Lookaside Buffer) entries. Your JVM and operating system should support this and most JVMs and operating systems do. Explaing how to configure large memory pages is out of the scope of this article. For Sun’ JavaSE implementation, I recommend following article: Java Support for Large Memory Pages
What if your latency requirements are not met by Java SE by only tuning your application and garbage collection? Then you may consider switching to a RTSJ compliant Java implementation. Since they are also certified as Java SE, porting your application may be very easy if you do not need hard real-time features. You should adopt RT specific features incrementally.
To be continued…
References:
- [Detlefs04] Detlefs, et. al., Garbage-First Garbage Collection, Sun Microsystems Research Laboratories, 2004.
- Dr. Dobb’s Article: G1: Java’s Garbage First Collector
- How to Configure Large Memory Pages for different operating systems? Java Support for Large Memory Pages
- Memory Mangement in HotSpot Virtual Machine. Download PDF.
Hi, There, I found your blog while surfing the net. This is an extremely well written article. I will make sure to bookmark it and come back to read more of your useful info. Thank You for the excellent post. Ill certainly comeback.