Generating native executable for Java
This blog is a continuation of my series, ‘Building Kubernetes-Native Microservices’..
Native Image is a technology to compile Java code ahead-of-time to a binary — a native executable. A native executable includes only the code required at run time, that is the application classes, standard-library classes, the language runtime, and statically-linked native code from the JDK
An executable file produced by Native Image has several important advantages, in that it
- Uses a fraction of the resources required by the Java Virtual Machine, so is cheaper to run
- Starts in milliseconds
- Delivers peak performance immediately, with no warmup
- Can be packaged into a lightweight container image for fast and efficient deployment
Brief about internals of JVM
Today’s Java is both an interpreted and a compiled language platform. Java started as an interpreted language platform: you save a source file with the .java extension and run the javac command to generate a .class file.That class file contains what’s called Java bytecode, a java language-specific interpretation of all the java code that you wrote.
When you now run “java yourcode.class”,theclassfile isinterpreted by the JRE into the OS-specific CPU instructions. That intermediate step of translating the class file into CPU-friendly instructions is carried out every time the code is run every method is reinterpreted for every time it needs to be run.
In the modern-day JVM, this would go on for a while, until some methods in your program or chunks of code are marked as “hotspots” — meaning the JVM has run these portions of the code many, many times.
At this point, the JVM will then execute a Just-In-Time (JIT) compilation of those hotspot portions. The thing is interpretation of the java bytecode slows down the execution.
JIT compilation produces durable assembly instructions that can be executed directly by the CPU. This means that there will be no need for the repeat interpretation. As you can imagine, that speeds up those specific parts of the application.
Below image depicts Traditional hotspot compilation
Ahead-of-Time Compilation to the Rescue!
Ahead-of-time (AOT) compilation takes compilation further, or rather brings it nearer. AOT compilation takes your .java files straight to compiled native binaries that can be immediately executed by the CPU, skipping the relentless interpretation step and passing the savings on to you.
Get Vinod Kumar Reddy Bathula’s stories in your inbox
Join Medium for free to get updates from this writer.
Your application starts up significantly faster, and most of the code enjoys the benefit of near immediate computability by the CPU. Additionally, the memory usage drastically shrinks The performance gains from this process are comparable to what the likes of C++ and GoLang.
Your entire application, if AOT-compiled, can even become a self- contained executable, without the need for a running, OS-supplied JVM
GraalVM
GraalVM is a high-performance, polyglot JVM distributed by Oracle. The GraalVM is an ability to take your .java file, straight to operating system-specific machine code, the so-called native image.
For Windows, you’ll get a .exe; for linux you will get linux binaries.
GraalVM works with a set of tools and utilities to generate an OS-specific image.With OS-specific tools, GraalVM scans your project’s code and maps out every class, method, and JVM feature that’s referenced in your code, directly or indirectly. It’s then able to AOT-compile the entire dependency tree and produce the native image that contains strictly what your code needs and nothing else.
Install GraalVm for Windows
- Download GraalVM community windows distribution from https://github.com/graalvm/graalvm-ce-builds/releases . Choose Java version and download respective zip.
- Extract to location. Set up JAVA_HOME environment variable to extracted location.
- Install Visual Studio build tools from Visual studio installer.
- After installation, search for “x64 Native Tools Command Prompt for VS 2019”. It opens up command prompt. Here you can run your native compilation commands.
Install GrralVm for Linux and MacOs
- Download linux distribution and extract to specific location
- Set JAVA_HOME with value as extracted location
Process is similar to MacOS. You have to run below command in termal to accept GraalVM binary to run by OSX
sudo xattr -r -d com.apple.quarantine graalvm-community-openjdk-<version>/Contents/Home/binThanks for reading., Stay tunes for upcoming blogs on “Implementing Kubernetes native microservice with Quarkus , Spring Boot Native and GoLang








