Eclipse OpenJ9 JVM Guide
Eclipse OpenJ9 JVM is a fast, efficient, and memory-optimized open-source Java Virtual Machine designed for cloud and enterprise applications. Let us delve into understanding the Eclipse OpenJ9 JVM and explore its features, performance options, and diagnostic capabilities.
1. What is Eclipse OpenJ9?
Eclipse OpenJ9 is a high-performance, scalable, and memory-efficient JVM (Java Virtual Machine) developed by the Eclipse Foundation. It is designed to optimize memory footprint and startup time while maintaining performance comparable to other JVMs like HotSpot. OpenJ9 is especially beneficial in containerized environments and cloud-native applications where memory and performance efficiency are crucial.
2. Installation
You can install OpenJ9 using prebuilt binaries from Adoptium or IBM Semeru. These builds are regularly updated and tested for performance and reliability. OpenJ9 binaries are available for multiple platforms including Linux, Windows, and macOS. You can choose between different versions (such as Java 8, 11, or 17) and download either the JDK or JRE based on your needs.
2.1 Linux Installation
On Linux, here’s a sample installation process using a tarball archive:
# Download and extract the OpenJ9 JDK wget https://github.com/ibmruntimes/semeru-open/releases/download/jdk-17.0.9+11_openj9-0.41.0/ibm-semeru-open-jdk_x64_linux_17.0.9_11_openj9-0.41.0.tar.gz tar -xvf ibm-semeru-open-jdk_x64_linux_17.0.9_11_openj9-0.41.0.tar.gz # Navigate to the extracted folder (adjust folder name based on extracted content) cd jdk-17.0.9+11 # Set JAVA_HOME and update PATH environment variable export JAVA_HOME=$(pwd) export PATH=$JAVA_HOME/bin:$PATH # Confirm installation java -version
You should see an output similar to the following when the installation is successful:
openjdk version "17.0.9" 2023-10-17 OpenJDK Runtime Environment (build 17.0.9+11) Eclipse OpenJ9 VM (build openj9-0.41.0, JRE 17 Linux amd64-64-Bit)
2.2 Windows Installation
On Windows, you can download a .zip package and extract it to a desired location. Then set the JAVA_HOME environment variable via System Properties and add %JAVA_HOME%\bin to the PATH.
After installation, you can start tuning and configuring OpenJ9 options based on your application needs, such as memory settings or garbage collection policy.
3. Garbage Collection Policies
Eclipse OpenJ9 provides a variety of garbage collection (GC) policies, each optimized for different workloads and runtime environments. These policies can be configured using the -Xgcpolicy option to fine-tune memory management based on your application’s needs.
-Xgcpolicy:gencon– The default policy. It uses a generational approach by dividing the heap into young and tenured regions, making it efficient for most applications with short-lived objects.-Xgcpolicy:balanced– Designed for applications with large heaps, it balances pause times and throughput by dividing the heap into equal regions and performing region-based collection.-Xgcpolicy:metronome– A real-time incremental GC policy that provides predictable pause times. Ideal for time-sensitive applications like audio/video processing or industrial control systems.-Xgcpolicy:optavgpause– Optimized to minimize average GC pause time, making it suitable for latency-sensitive but not strictly real-time systems.
To use a specific policy, pass it as an option during application startup. Example using the GenCon policy:
java -Xgcpolicy:gencon MyApp
3.1 Sample Java Code to Trigger Garbage Collection
The following simple program creates temporary objects and explicitly suggests a garbage collection using System.gc(). Note that the JVM is free to ignore the suggestion.
// GCDemo.java
public class GCDemo {
public static void main(String[] args) {
for (int i = 0; i < 100_000; i++) {
String[] temp = new String[1000]; // Create temporary objects
}
System.gc(); // Suggests JVM to perform garbage collection
System.out.println("Garbage collection requested.");
}
}
The following output is returned upon executing the code:
Garbage collection requested.
For advanced monitoring and tuning, you can use additional flags such as -verbose:gc to log GC activity, or integrate OpenJ9 with tools like Eclipse Memory Analyzer or JConsole to analyze GC behavior over time.
4. Class Data Sharing and AOT Compilation
4.1 Class Data Sharing (CDS)
Class Data Sharing (CDS) allows the JVM to store class metadata in a shared cache that can be reused across JVM instances. This significantly improves startup time and memory footprint, especially in environments where many Java applications or JVMs are launched repeatedly (e.g., microservices or serverless platforms). The shared cache is stored in memory or on disk and can be reused as long as the classes remain compatible.
Example to create and use a shared class cache:
# Create a shared cache named 'MyCache' and initialize it with the JDK system classes java -Xshareclasses:name=MyCache -Xscmx50M -version # Launch an application using the same shared class cache java -Xshareclasses:name=MyCache -Xscmx50M MyApp
Useful options:
-Xshareclasses:name=CacheName– Specifies the name of the cache.-Xscmx<size>– Sets the maximum cache size (e.g.,50M).-Xshareclasses:cacheDir=<path>– Optionally specify the location of the shared cache.
To inspect the cache contents:
java -Xshareclasses:name=MyCache,listAllCaches
CDS is particularly beneficial in containers, where startup latency is critical.
4.2 Ahead-of-Time (AOT) Compilation
Ahead-of-Time (AOT) compilation enables you to compile Java bytecode into native code before runtime. This reduces the Just-In-Time (JIT) compilation overhead and improves application startup performance, especially in cold-start scenarios. AOT is most useful for:
- Reducing CPU consumption in high-scale deployments
- Improving performance predictability
- Minimizing JIT warm-up time for command-line tools and short-lived processes
Example of compiling and using AOT:
# Compile MyApp class to a shared native library (AOT) jaotc --output MyApp.so --class-name MyApp # Run the application using the AOT-compiled code java -Xjit:aot -Xaot:loadAOTLibs=MyApp.so MyApp
Notes:
jaotcis the Java AOT compiler tool, available in certain OpenJ9 builds.- The
--outputflag specifies the native shared object (.so) file to be generated. - Use
-Xjit:aotto enable JIT to take advantage of AOT-compiled methods. - Use
-Xaot:loadAOTLibsto load the specific AOT library at runtime.
AOT can be combined with CDS for even faster startup, making it ideal for performance-sensitive deployments like serverless functions or JVM-based CLI tools.
5. Diagnostic Data and Tooling
Eclipse OpenJ9 provides a comprehensive set of diagnostic tools and runtime options to help developers and system administrators monitor, troubleshoot, and optimize Java applications in real time. These features are especially valuable in production environments for root cause analysis and proactive tuning.
-Xdump– Configures automated or manual generation of diagnostic data such as heap dumps (.phd), Java dumps, and system dumps during events like exceptions, signals, or JVM crashes.-Xtrace– Enables fine-grained tracing of internal JVM operations. You can trace specific modules or events to debug native or Java-level execution flows.-Xtune– Used to apply predefined tuning profiles (e.g.,throughput,footprint, orlatency) to optimize application behavior without deep manual tuning.jcmd,jstack,jmap– Standard Java diagnostic tools supported by OpenJ9, used to inspect thread dumps, memory usage, heap state, and class histograms at runtime.
Example: Generate a heap dump when an OutOfMemoryError occurs:
java -Xdump:heap:events=systhrow,filter=java/lang/OutOfMemoryError,request=exclusive+prepwalk MyApp
This command sets up the JVM to automatically produce a heap dump (heapdump.phd) when an OutOfMemoryError is thrown. The prepwalk keyword ensures the heap is walkable for post-processing analysis. You can analyze the resulting .phd file using tools like:
- Eclipse Memory Analyzer (MAT) – Visual tool for analyzing heap contents and identifying memory leaks.
jdmpview– A command-line tool provided by IBM/OpenJ9 to explore dumps in detail.
5.1 Java Diagnostic Code Example
The following example simulates a memory leak scenario by continuously allocating memory. When the JVM exhausts available heap space, it throws an OutOfMemoryError and triggers the dump:
import java.util.ArrayList;
import java.util.List;
public class MemoryLeak {
public static void main(String[] args) {
List<byte[]> list = new ArrayList<>();
while (true) {
list.add(new byte[1024 * 1024]); // Allocate 1MB chunks
}
}
}
The following output is returned upon executing the code:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space Heap dump will be written to: heapdump.phd
These diagnostic capabilities make OpenJ9 a production-grade JVM suitable for enterprise-scale systems with demanding observability requirements.
6. Conclusion
Eclipse OpenJ9 offers a versatile and efficient JVM alternative with advanced capabilities like garbage collection tuning, shared class caches, and AOT compilation. Its lightweight footprint and fast startup make it an ideal choice for microservices and cloud applications. By understanding its configuration options and diagnostic tooling, developers can build more performant, resilient, and scalable Java applications.

