The Ahead of Time (AOT) Compiler

Ahead of time (AOT) compilation - cartoon of man winning a race

Last week we looked at some of the JVM command line options that customise how the interpreter and JIT compiler work. This week we’ll look at the AOT compiler that was introduced experimentally in Java 9 (and removed in Java 16 – more on that later).

What is AOT Compilation?

To recap on some points from the previous post, the HotSpot JVM contains a JIT compiler to speed up Java applications at runtime. The HotSpot JVM profiles a running program, and then selectively optimizes sections of code it decides will have the greatest speed benefit. These hot spots are compiled into native code on the fly.

JIT compilers are fast, but when running large Java programs the JIT can take a long time to warm up completely. Rarely used methods might never even be compiled, and are then only executed by the interpreter. This can potentially cause performance hits.

Ahead of Time (AOT) compilation takes a different approach to the JIT. An AOT compiler compiles Java classes to native code before running the Java application. This is one way of improving the performance of Java applications, and in particular the startup time of the JVM.

It’s self-evident that if the bytecode methods have already been compiled, the application should run faster. The JVM doesn’t need to use extra CPU cycles profiling the code and running the JIT. The JVM can just load and run the previously compiled methods. An application can reach its peak runtime performance much faster because the JVM doesn’t need to warm up.

AOT Types

There are two main ways in which we can do AOT:

  • Static AOT involves compiling every method in a set of classes before running the code. This preliminary step creates a library of pre-compiled native machine code that is loaded at runtime by a JVM. This is similar to pre-compiling native methods into a loadable library.

  • Dynamic AOT involves compiling methods at runtime. The application must be profiled during runtime to determine which methods should be compiled.

How Does AOT Work?

AOT compilation was introduced into JDK 9 as an experimental feature with JEP 295: Ahead-of-Time Compilation.

AOT compilation is done with a new tool called jaotc. This is a static AOT compiler that generates native code as shared libraries for the Java methods in specified class files. The JVM can load these AOT libraries and directly call the native code. There is no need for the JIT compiler to compile bytecode into native code.

During JVM startup the AOT initialization code looks for shared libraries in specific locations, or as specified with the AOTLibrary command line flag. If any compiled libraries are found, they are used. If none are found then AOT is disabled for the current JVM instance.

The AOT compiler uses Graal as the back-end to generate the native code. The Graal compiler is written in Java, and is called using the JVM Compiler Interface (JVMCI).

The Graal compiler was used as an experimental JIT compiler in JDK 10 via JEP 317: Experimental Java-Based JIT Compiler.

AOT Compilation Process

Before we can use the AOT compiler, we must compile the class(es) as usual with the Java compiler:

javac HelloWorld.java

We then pass the compiled class file (containing bytecodes) to the jaotc AOT compiler. This compiles the bytecodes into a library containing native machine code:

jaotc --output libHelloWorld.so HelloWorld.class

This library is then used when running the application:

java -XX:AOTLibrary=./libHelloWorld.so HelloWorld

When we run an application with this command, the JVM will automatically use the AOT compiled libraries. If we find that our application starts up more slowly, runs slower than expected or even crashes, we can switch AOT off with the -XX:-UseAOT flag, or we can just delete the AOT libraries.

The same JDK configuration must be used during both AOT compile time and runtime. The Java version is registered in the AOT libraries and checked when loading. AOT recompilation is needed when the Java version is changed and/or when we make changes to the Java source code files (obviously).

Removal of AOT from OpenJDK

The Java-based AOT and JIT compilers were experimental features that did not see much community adoption. They were optional features and were removed from JDK 16. JEP 410 removes these components from the JDK source code.

GraalVM

Even though the AOT compiler has been removed from OpenJDK it doesn’t mean it’s dead. Far from it! It’s alive and well in a number of Java projects. One of the leading AOT projects is Graal.

The Graal project originated in Oracle Labs and is not part of OpenJDK. The Graal project has a number of tools including a full VM called GraalVM with a high performance JIT compiler and a number of monitoring and development tools.

The GraalVM Native Image tool is a stand-alone Java AOT compiler that produces native code executable files. These provide a number of advantages over Java’s JIT compiler: faster startup, smaller file sizes, lower memory and CPU usage, and improved security. These executables can be used in stand-alone Java applications; inside frameworks like Spring; inside containers like Docker; in the cloud, and as microservices.

Ending Off

In next week’s post, we’ll look at some features of the garbage collectors that are available in the JVM.

Don’t forget to share your comments and Java experiences.

Stay safe, and I’ll see you next week!

Leave a Comment

Your email address will not be published. Required fields are marked *

Code like a Java Guru!

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email info@incusdata.com

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.

Your Java tip is on its way!

Check that incusdata.com is an approved sender, so that your Java tips don’t land up in the spam folder.

Our privacy policy means your data is safe. You can unsubscribe from these tips at any time.