Intel AS/400 RISC Server User Manual

Page 129

Advertising
background image

performance, it pays to apply analysis and optimizations to the Java bytecodes, and the resulting machine
code.

One approach to optimizing Java bytecode involves analyzing the object code “ahead of time” – before it
is actually running. This “ahead-of-time” (AOT) compiler technology was used exclusively by the
original AS/400 Java Virtual Machine, whose success proved the power of such an approach.

However, any static AOT analysis suffers one fatal flaw: in a dynamically loading language such as Java,
it is impossible for an AOT compiler to know exactly what the environment will look like when the code
is actually being executed. Certain valuable optimizations – such as inter-class method inlining or
parameter-passing optimizations – cannot be made without adding extra checks to ensure that the
optimization is still valid at run-time. While these checks are trimmed down as much as possible, some
amount of overhead is unavoidable.

When Java was first introduced to the AS/400 it used an AOT compilation approach, with a combination
of bytecode interpretation and Direct Execution (DE) programs to statically optimize Java code for the
OS/400 environment, with startup and runtime performance usually significantly faster than what other
Java implementations at the time could provide.

Later, “Just-In-Time” (JIT) compiler technology was introduced in many Java VMs. Unlike AOT
compilation, JIT compiles Java bytecodes to machine code on-the-fly as the application is running. While
this introduces some overhead as the compilation occurs, the compiler can optimize much more
aggressively, because it knows the exact state of the system it is compiling for.

Over time, JIT compilation technology improved and was implemented alongside DE in the i5/OS Classic
VM. JIT performance overtook DE in the V5R2 time frame for most applications, and has continued to
improve at a faster rate. In V6R1, support for DE was eliminated, so the JIT will be used for all Java
applications.

Despite the improvements to JIT for both runtime and startup performance, startup time does tend to be
slightly longer for JIT than DE. Beginning in V5R2, the Mixed Mode Interpreter (MMI) is used to
interpret code until it has been executed a number of times (2000 by default, can be overridden by setting
the system property

os400.jit.mmi.threshold

) before JIT compiling it, resulting in improved

startup time. V5R3 introduced asynchronous JIT compilation, which further improved startup time,
especially on multiprocessor systems. As a result of these and other improvements, many applications
will no longer see a significant difference in startup time between DE and JIT. Even if startup time is a
bit longer with JIT, the improvement in runtime performance may be worth it, especially for long-running
applications which don’t start up frequently.

Prior to V6R1, the default execution mode is “

jitc_de

”, which uses DE for Java classes which already

have DE programs, and JIT for classes which do not. Notably, JDK classes are shipped with DE program
objects created, and will therefore use DE by default. Set the system property

java.compiler

to

jitc

to force JIT to be used for all Java code in your application. (See InfoCenter for instructions about setting
Java system properties.)

Note that even when running with the JIT, the VM will have to create a Java program object (with
optimization level *INTERPRET) the first time a particular Java class is used on the system, if one does
not already exist. Creation of this program object is much faster than creating a full DE program, but it
may still make a noticeable difference in startup time the first time your application is used, particularly in

IBM i 6.1 Performance Capabilities Reference - January/April/October 2008

©

Copyright IBM Corp. 2008

Chapter 7 - Java Performance

129

Advertising
This manual is related to the following products: