Sun Java Real-Time System 2.2

This guide gets you started quickly with Sun Java™ Real-Time System (Java RTS).

Technical Documentation: Links to all the Java RTS technical documents

See also the Sun Java Real-Time System FAQ (Frequently Asked Questions) for a comprehensive, though not exhaustive, list of questions and answers about Java RTS.


Step 1. Check Your Java RTS Installation
Step 2. Identify Real-Time Threads
Step 3. Configure the Compilation System
Step 4. Configure the RTGC for Hard Real-Time
Step 5. (Optional) Tune the RTGC for Soft Real-Time
Step 6. Run Your Program
Step 7. Verify the System Configuration
The Example Program
Further Reading of Java RTS Documentation


The main characteristic of a real-time application is that the system is subject to real-time constraints. Worst-case response times must be deterministic, in other words, predictable within given limits. The Sun Java Real-Time System guarantees determinism by ensuring that time-critical code is executed at the highest priority, even higher than the garbage collector (GC) if needed.

The first Java Specification Request (JSR) issued by the Java Community ProcessSM (JCP) was JSR 1: the Real-Time Specification for Java (RTSJ). The Sun Java Real-Time System (Java RTS) is Sun's implementation of that specification, including a Real-Time Garbage Collector (RTGC).

We define non-real-time and real-time requirements for an application as follows:

  • A non-real-time application has no time constraint requirements.

  • In a real-time application, response times must be deterministic.

    • In a soft real-time application, missing an occasional deadline can be tolerated.

    • In a hard real-time application, time constraints must always be met.

Real-time does not (necessarily) mean "real fast," and therefore Java RTS is more concerned with determinism than with speed. However, the platform does indeed incorporate many features that improve throughput while still guaranteeing determinism.

Determinism can be expressed in terms of jitter, which is central to measuring the deterministic behavior of a program. Jitter measures the variation in a particular response time for a particular computational scenario of interest within a given executing application. With respect to determinism, an ideal value for jitter would be zero, indicating perfect predictability. More realistically, the aim of real-time processing is to reduce jitter to an acceptable level. Moreover, any jitter that occurs must be bounded, that is, we must guarantee that the jitter remains within known bounds.

Java RTS implements not only the Real-Time Specification for Java (RTSJ), but also the specification for Java™ Platform, Standard Edition (Java SE). Therefore, a program that runs on the Java SE platform will also run on the Java RTS platform, although without real-time behavior.

The easiest way to get off to a quick start with Java RTS is to convert an existing Java SE application to Java RTS.

Following the steps below can help you improve the determinism of your application.

In addition, an example program is provided at the end of this document.

Step 1. Check Your Java RTS Installation

We assume that you have already installed Java RTS for your platform according to the instructions in the Java RTS Installation Guide. Check your installation as follows:

  • The Unix shell environment must be configured in order to ensure that the relevant executables (primarily java and javac) and libraries in your Java RTS installation are picked up when referenced by name.

    Check that the environment variable JRTS_HOME is set to the absolute path of your Java RTS installation, and that $JRTS_HOME/bin is at the beginning of the list of paths specified by the PATH environment variable.

  • Ensure that you have configured real-time privileges for Java RTS users, as described in the Installation Guide. If these privileges are not granted, your application can fail with messages such as "You don't have the privilege to use high-resolution timers", or "insufficient effective privileges; temporal behavior is not predictable."

  • Check that the correct java launcher (that is, from your Java RTS installation) is being picked up, by executing the command java -version. The output of the command should include the string Java Real-Time System HotSpot(TM) Client VM.

Note: (Solaris OS) In order to execute the 64-bit Java RTS VM, add the -d64 option to the command line, as described in Executing the 64-Bit VM in the Java RTS Installation Guide.

Step 2. Identify Real-Time Threads

Real-time threads are those which must execute within certain limits, that is, in a predictable, deterministic way. Most applications will have a few real-time threads, while the remaining threads are non-real-time, that is, they do not have rigid temporal constraints. Non-real-time threads are instances of the class java.lang.Thread. Java RTS provides a subclass of java.lang.Thread, called javax.realtime.RealtimeThread (RTT). Instances of this class will exhibit "soft" real-time behavior by default. By properly setting the thread priorities (as explained below), you can cause some real-time threads to exhibit "hard" real-time behavior. You need to identify which threads of your application must be RTTs and instantiate them with the RealtimeThread class.

You also need to make sure that the priorities assigned to threads reflect their importance. In addition to the 10 regular Java priorities, Java RTS features a number of unique real-time priority levels, where this number depends on the host operating system (Solaris OS or Linux). A real-time thread of a lower priority can be preempted in its execution by a real-time thread of a higher priority.

Real-time threads can be non-critical (soft real-time) or critical (hard real-time), and this distinction is determined by the critical priority boundary. Real-time threads whose priority is above the critical boundary are called critical real-time threads, while those below the boundary are called non-critical real-time threads. The default for this boundary is the middle of the real-time range, and is OS-dependent.

To determine the minimum and maximum real-time priorities available, use the methods getMinPriority() and getMaxPriority(), respectively, of the javax.realtime.PriorityScheduler.instance().

In addition to having a higher priority, critical real-time threads benefit from a user-defined amount of memory reserved for their use, as explained in Step "Configure the RTGC for Hard Real-Time."

Define a critical real-time thread if and only if it has a definite time constraint. Otherwise, there could be too much competition among these threads for resources.

For a detailed description of Java RTS thread types and their priorities, see the Java RTS Garbage Collection Guide.

Step 3. Configure the Compilation System

The standard compilation scheme for a Java program can break the determinism of a real-time program, because the following activites can occur during time-critical phases of program execution:

  • A Java program runs interpreted until a certain threshold is reached and compilation occurs. This is called Just-In-Time (JIT) compilation. But the compilation causes jitter in the program execution, and this breaks determinism.

  • In addition, classes are lazily initialized, that is, when they are first used, and this is also non-deterministic.

  • Finally, symbol references are resolved on-demand. Since this resolution can occur at any time, determinism is not possible.

Java RTS provides the Initialization-Time-Compilation (ITC) scheme, which solves the problems described above by allowing you to control the following:

  • Methods to be precompiled when their classes are initialized. These methods are specified in the precompile list.
  • Classes to be preinitialized at VM startup. These classes are specified in the preinit list.

The Java RTS Compilation Guide contains a detailed description of the compilation modes (schemes) for the various thread types and how to configure them.

If you perform no configuration at all, then the run-time compilation can cause jitter that breaks your application's determinism.

However, for purposes of getting started quickly, you can run your application with special Java RTS command-line parameters that specify the automatic creation of files containing the precompile and preinit lists.

The precompile and preinit files are cumulative, that is, each time you run the application, more methods and classes can be added to the files. Therefore, you should run the application as many times as necessary to ensure that all the time-critical real-time code has been executed, which ensures that the precompile and preinit lists are complete. You might want to run the application with various arguments or in various conditions in order to ensure code coverage. Once code coverage is complete, your real-time application should not suffer from jitter caused by symbol resolution, class initialization, or execution-time compilation.

You can use the following command as an example of a minimum level of ITC configuration:

java \ -XX:+RTSJBuildCompilationList \ -XX:+RTSJBuildClassInitializationList \ -XX:CompilationList=nhrt.precompile \ -XX:PreInitList=itc.preinit \ <application> <arguments>

Here is the explanation of what is happening with the example command above:

  • By default, ITC is enabled for RTTs and NHRTs. This means that, when an RTT or NHRT executes, the methods in the precompile list are compiled when their classes are initialized, and all other methods are JIT-compiled for RTTs or interpreted for NHRTs.

  • With the RTSJBuildCompilationList command-line option, Java RTS automatically generates a file containing a list of the methods that were invoked by RTTs or NHRTs; this is the precompile list. The default file name for the precompile list is nhrt.precompile. This file is cumulative, that is, each time you run the application, more methods can be added to the file.

  • With the RTSJBuildClassInitializationList command-line option, Java RTS automatically generates a file containing a list of the classes that were referenced during the compilation of methods at initialization; this is the preinit list. The default file name for the preinit list is itc.preinit. This file is also cumulative, that is, each time you run the application, more classes can be added to the file.

  • The precompile and preinit lists that Java RTS has generated are used in each run of the same application in order to reduce jitter. The use of these files is specified with the -XX:CompilationList and -XX:PreInitList command-line parameters.

  • The first time you run the command, Java RTS generates the initial precompile and preinit files.

    As mentioned above, you should run the application as many times as necessary to ensure code coverage.

  • If you run a different application, remember to remove or rename the precompile and preinit files, as they are cumulative.

Step 4. Configure the RTGC for Hard Real-Time

Java RTS includes a Real-Time Garbage Collector (RTGC). This GC can be tuned in various ways to get the best determinism for any given application. However, to get started, only a minimum amount of configuration is necessary.

The RTGC guarantees determinism to critical real-time threads by reserving memory for these threads. This amount of memory is specified with the command line parameter RTGCCriticalReservedBytes. If free heap memory falls below this amount, the non-critical real-time threads are blocked on memory allocation, waiting for the RTGC to recycle memory. This guarantees that the critical real-time threads, and only the critical real-time threads, will be able to allocate memory from this reserved amount. Therefore, you must specify a value for this reserved amount that will ensure that your critical threads will not fail on memory allocation. On the other hand, if RTGCCriticalReservedBytes is too high, the RTGC will run too often and block non-critical threads. This decreases the throughput.

Another parameter, RTGCCriticalBoundary, specifies the priority boundary between critical real-time and non-critical real-time threads. The default for this boundary is the middle of the real-time range, and is OS-dependent. You can modify this command-line parameter to suit the range of thread priorities in your application. The RTGC must get enough CPU time to recycle memory quickly enough for the needs of the critical threads.

You can leave the other parameters at their default values, but if your application does not exhibit the desired determinism, you can try some basic tuning of the RTGC (see the next step).

See the Java RTS Garbage Collection Guide for a detailed description of how the RTGC works.

Step 5. (Optional) Tune the RTGC for Soft Real-Time

The default values for the RTGC parameters should be sufficient for getting started with Java RTS. Optional advanced tuning is described in detail in the Java RTS Garbage Collection Guide.

Java RTS uses a sophisticated auto-tuning mechanism to determine the optimal conditions under which to start the RTGC or boost its priority to a higher level. At the end of each garbage collection cycle, Java RTS calculates a memory threshold based on previously allocated memory and other factors in order to predict how memory might be allocated during the next cycle. It is best to allow this procedure to run with its default values.

The RTGC is fully concurrent, that is, it can recycle memory without stopping your threads. However, it must get enough CPU time to recycle memory faster than the threads consume it. At the same time, you need to find the balance between throughput and predictability (determinism). If you have sufficient CPU time available, you can try changing the number of parallel RTGC worker threads.

Step 6. Run Your Program

Run your program with, for example, the following command. See the next section for an explanation of PrintGC and LogJitterProneEvents. (See also the example in the step "Configure Compilation System.")

java \
-XX:+RTSJBuildCompilationList \
-XX:+RTSJBuildClassInitializationList \
-XX:CompilationList=<precompile-file-name> \
-XX:PreInitList=<preinit-file-name> \
-XX:RTGCCriticalReservedBytes=<amount> \
-XX:+PrintGC \
-XX:+LogJitterProneEvents \
<application> <arguments>

Step 7. Verify the System Configuration

Use one or more of the following suggestions to check whether your system was correctly configured for your application to be determinstic:

  • The command-line option PrintGC prints GC information after each GC cycle, and this can help solve simple GC issues. The values that are noted "worst" represent values since VM startup, whereas the "min" and "max" values occurred during the last GC cycle. If the "worst" non-fragmented (that is, available) memory falls to zero, this means that at least one thread was blocked during allocation. If you have critical real-time threads, you should increase the value of RTGCCriticalReservedBytes, that is, the memory reserved for critical real-time threads. In fact, even if the "worst" amount is not zero but is very low, you should increase the reserved bytes for critical threads, for safety's sake. See the Garbage Collection Guide for more details.

  • The command-line option LogJitterProneEvents produces a log file of various events that can cause jitter. See the Java RTS Tools, Tuning, and Troubleshooting Guide for details.

  • For more complex issues, you can use the Thread Scheduling Visualizer (TSV). This tool set includes customizable DTrace scripts to record scheduling events in Java RTS, as well as a visualizer to provide a graphic view of these events. For example, you can use TSV to visualize the activity of the compilation thread and GC thread. See the next step ("Further Reading," subsection "Tools and Troubleshooting") for information about how to obtain TSV.

  • You should use the RTSJ real-time API Clock to perform measurements. It is best not to use other clocks (for example, java.util.Date or java.lang.System.currentTimeMillis). For some of these other clocks, the time base is different, synchronized with the world clock. This synchronization can cause jitter when the world clock is updated.

The Example Program

The HelloWorldRT program provides a very basic example of a real-time program that uses the Java RTS Application Programming Interface. This program runs a periodic thread that measures the observed differences (that is, latency) between the expected scheduling time and the effective activation time at each period. At the end of the run every latency greater than 100 microseconds is reported. The worst (highest) latencies observed since the beginning of the run are also reported. The chosen period is 2 milliseconds and the number of loops in the run is 10000. You are fee to change these constant values in the source code.

Note that this example program allocates very little memory, unlike a typical application, and therefore we have no need to configure the Real-Time Garbage Collector.

We show in this section how to compile and run this program. The source code of the HelloWorldRT program is provided together with this Quick Start Guide.

We suppose in the scenarios below that the source code file HelloWorldRT.java has been copied to the /tmp directory on the machine on which Java RTS has been installed.

Compile the HelloWorldRT example

Change directory to /tmp and run the following command:

javac HelloWorldRT.java

The /tmp directory now contains two additional class files: HelloWorldRT.class and HelloWorldRT$PeriodicThread.class.

Produce stabilized ITC compilation lists

Now run three times the following command to generate ITC compilation system data to be used in further runs:

java \
-XX:+RTSJBuildCompilationList \
-XX:+RTSJBuildClassInitializationList \
-XX:CompilationList=nhrt.precompile \
-XX:PreInitList=itc.preinit \

After the second run the generated nhrt.precompile file should stabilize and remain unchanged from that point.
After the third run, both the nhrt.precompile and the itc.preinit files should be unchanged.

Run the HelloWorldRT program with finalized compilation lists

You can now run the program without generating ITC compilation files to avoid any impact on the deterministic behavior due to the ITC compilation system:

java \
-XX:CompilationList=nhrt.precompile \
-XX:PreInitList=itc.preinit \

Below is a sample output of a run of the HelloWorldRT program:

Hello Real-Time World !
 Number of iterations = 10000
 Period value = 2 milliseconds (ms)
Real-time thread execution finished.

Noticeable latencies (values >= 100 microseconds) in order of occurrence (if any):
 Loop 2709: Rescheduling time  = (1255594555195 ms, 473904 ns); 
                         Noticeable latency = (0 ms, 107078 ns)

Highest latency values in increasing order:
 New highest latency at loop 2 = (0 ms, 5419 ns)
 New highest latency at loop 3 = (0 ms, 5832 ns)
 New highest latency at loop 84 = (0 ms, 7508 ns)
 New highest latency at loop 1336 = (0 ms, 26563 ns)
 New highest latency at loop 1347 = (0 ms, 31552 ns)
 New highest latency at loop 2709 = (0 ms, 107078 ns)

Bye, Real-Time World ...

Further Reading of Java RTS Documentation

All of the Java RTS technical documents contain information that will help you continue your successful experience. The latest versions of these documents are available on the Java RTS Technical Documentation web page.

Basic Information

Installation Guide - Install the Java RTS virtual machine, the kernel modules, and grant privileges to users.

Release Notes - Check release-specific details.

Compilation Guide - Configure the compilation system for maximum determinism.

Garbage Collection Guide - Configure the Real-Time Garbage Collector for maximum determinism.

Java RTS Command-Line Options - Consult the list of command-line options that are specific to Java RTS.

Advanced Information

Technical Information - Learn even more details for improved programming success.

A Practical Introduction to Achieving Determinism - Play with a set of example programs to see how various parameters can affect determinism.

Tools and Troubleshoting

Java RTS DTrace Provider Guide (Solaris OS only) - Use the special DTrace probes provided for use with Java RTS.

Java RTS Tools, Tuning, and Troubleshooting Guide - Get help with troubleshooting.

The Thread Scheduling Visualizer (TSV) tool and accompanying guide. You can download the TSV tool at the same time you download a Java RTS Evaluation. For your convenience, a link to the TSV guide alone is provided on the Java RTS Technical Documentation web page.



For comments and questions, please contact Java RTS Engineering and Marketing.


Copyright © 2009 Sun Microsystems, Inc. All Rights Reserved.