Java JIT and RTI Connext DDS Java Application Real-Time Pitfalls

 

The Java JIT compiler is discussed in the following article:

https://www.ibm.com/support/knowledgecenter/en/SSYKE2_8.0.0/com.ibm.java.vm.80.doc/docs/jit_overview.html

 

As the article says, “The Just-In-Time (JIT) compiler is a component of the runtime environment that improves the performance of Java™ applications by compiling bytecodes to native machine code at run time.”

 

What does that mean to Connext DDS Java developers? Consider the following Java code snippet from a Connext DDS data subscriber application:



        public void on_data_available(DataReader reader) {

            final StringDataReader stringReader = (StringDataReader) reader;

            final SampleInfo sampleInfo = new SampleInfo();

 

            while (true) {

                try {

                    // ------------------------------

                    // Read the incoming data.

                    // ------------------------------

                    final String sample = stringReader.take_next_sample(sampleInfo);

                    if (sampleInfo.valid_data) {

                           // Process data here...

                        }

                    }

                } catch (final RETCODE_NO_DATA noData) {

                    // No more data to read

                    break;

 

                } catch (final RETCODE_ERROR e) {

                    e.printStackTrace();

                }

            }

        }

 

The on_data_available callback is processed in the Connext DDS receive data thread. The take_next_sample API is executed every time a sample arrives. If samples are being received at a high rate, the Java JVM will note this and after a certain number of executions, the JIT will rebuild the take_next_sample procedure in native byte code to be more efficient. This rebuild can take hundreds of milliseconds. During this time, take_next_sample is blocked. The on_data_available callback and the receive thread are blocked, too. This results in the take_next_sample API taking longer than usual, until JIT finishes its one-time rebuild of take_next_sample.

 

There are two workarounds. The first is to preemptively execute the Java procedure that may be affected by the JIT a number of times, perhaps 100 times, to invoke the JIT compiler. The second is to use the -Xint Java command-line argument, which disables the JIT.

Programming Language:
Keywords: