Real-Time Java Solutions
In the late '90s, a group of real-time and programming language experts from around the globe worked together to define a specification to define how Java should behave in the real-time space. The result was the Real-Time Specification for Java (RTSJ), which doesn't change the Java language at all, but instead outlines areas of enhancement to the platform to meet real-time requirements. These include:
- Thread scheduling: The RTSJ states that a real-time scheduler be used to schedule tasks, but it doesn't specify the algorithm, nor how to do it. RTSJ implementations typically rely upon and work with the OS to achieve this goal. RTSJ does, however, define new thread types — i.e., RealtimeThread (RTT), and NoHeapRealtimeThread (NHRT) — for real-time Java execution.
- Memory management: The RTSJ doesn't require a garbage collector, nor does it specify any algorithms for it. Instead, it defines new memory regions beyond the heap, and specifies that the collector not interfere with them. Therefore, it's possible to perform memory management outside the scope of the Java GC.
- Resource sharing: With enhanced thread scheduling comes the need for thread priority control. The RTSJ requires the priority inheritance protocol be implemented through the Java synchronized keyword, along with a set of wait-free queues.
- Asynchronous execution control: To control asynchronous event handling, the RTSJ defines how event-handling code is to be scheduled and dispatched deterministically. It also extends the Java exception handler to allow immediate shifts of execution within a real-time thread. Finally, it defines a way to terminate a thread's execution safely and deterministically.
- Physical memory access: The ability to create and access objects within specific regions of physical memory is defined, allowing Java code to interact with IO and other hardware devices deterministically, and with minimal latency.
The overarching goal of the RTSJ is to not change the Java language (for example, it included no new keywords), but to allow the average Java developer to build real-time software. However, that's not to say some changes in coding practice aren't required. Let's take a quick look at how the RTSJ affects Java programming.
RTSJ In Practice
The Java developer needs to embrace some new concepts to use RTSJ. For instance, the two new thread classes described previously require developers to specify certain aspects of their behavior. These include priority, scheduling behavior (periodic or aperiodic), and memory region requirements. For instance, while an RTT can access objects that reside anywhere, an NHRT can't access objects that reside on the heap. The RTSJ defines additional memory regions where objects can reside, to ensure no interference with the Java garbage collector. These regions include ScopedMemory, ImmortalMemory, and PhysicalMemory.
A ScopedMemory region is an area of memory outside of the Java heap that can be defined and created at runtime, and within which Java objects are created. When the real-time code finishes with the region (something the developer controls), the entire region and the objects it contains are marked as free, and all references to them are removed; no GC is required.
The sole ImmortalMemory region is an area of memory where Java objects live for the life of the VM. Objects created here are never collected, nor are they freed in any way. Hence, ImmortalMemory is a limited resource meant to provide deterministic access to data commonly needed within a real-time Java application.
There are sometimes complex rules for object reference and access between the various memory regions, but I won't go into those details here. Those details(as well as asynchronous event handling, asynchronous transfer of control, and physical memory access) can be reviewed in the RTSJ documentation or in one of the books written on the topic.
Real-Time Java Implementations
RTSJ has seen a few revisions over the years, and it's still actively being improved. For instance, JSR-282 is in the early draft review stage, and will define version 1.1 of the RTSJ. Be sure to look at the current specification, and then the proposed revision, to get a feel for where things are headed.
Officially compliant RTSJ implementations include the Sun (now Oracle) Java Real-Time System, the IBM WebSphere Real-Time VM, and the Timesys RTSJ reference implementation. Both Oracle and IBM provide support for multiple operating systems, including Solaris and specific Linux distributions (real-time scheduler required).
There are currently no RTSJ-compliant implementations available for Windows, but not because of the common misconception that Windows cannot provide real-time behavior. To some degree, it can, via its real-time thread support; but it simply doesn't provide enough real-time thread priority levels to meet the RTSJ's requirements.
The common Linux distributions also do not meet the RTSJ's requirements for real-time systems. Instead, IBM provides its own real-time Linux variant to guarantee real-time behavior, and Oracle requires you use either Red Hat's Messaging-Realtime-Grid (MRG) Linux distribution, or Novell's Suse Linux Enterprise Linux extensions (SLERT) for Suse Linux Enterprise Server.
Real-Time, Without RTSJ
There are other real-time Java implementations that aren't strictly RTSJ-compliant, although they may implement most or part of the API. These include:
- Aicas JamaicaVM: A Java SE/RTSJ compatible implementation with a real-time, deterministic garbage collector.
- Aonix PERC: A Java SE/RTSJ compatible implementation with its own real-time, deterministic garbage collector. Aonix also has support for embedded devices with memory limitations, as well as systems with safety-critical requirements.
- Fiji: A small-footprint Java implementation for embedded systems with deterministic garbage collection and support for safety-critical systems.
- Javolution: A real-time Java library that provides a set of classes for deterministic execution, and RTSJ support.
Again, true real-time Java development goes beyond the need for just real-time garbage collection. When choosing a real-time Java VM, whether it's RTSJ-compliant or not, be sure to choose one that guarantees your application will meet time-based requirements, with enough support to deterministically schedule your application's processing. Let's take a look at some areas real-time Java is being used today.
Business Success Cases
I've personally evaluated and deployed real-time Java in a wide range of applications. The types of applications include financial applications, including trading engines, quote publishing, news delivery; military systems, such as object tracking and flight control; telecommunication systems; and other specialized projects, including embedded systems, robotics, and embedded controllers.
Specific projects include a trading system developed at Reuters, embedded systems development at Perrone Robotics, a space object tracking system at ITT, flight systems at Boeing, and various military projects.
Most of these projects have been a big improvement over using specialized languages and programming environments that would have otherwise been required. Projects where real-time Java sometimes doesn't fit are ones where non-real-time requirements are mixed in, such as the need for high transaction rates and overall throughput. These are two areas that often require a trade-off to achieve predictable real-time behavior.
As tight time requirements become a greater part of enterprise computing, it's helpful to know that the same Java language and tooling used for developing standard applications can also be used to create deterministic, real-time computing solutions.