0.18.1 / January 24, 2020
|Written in||C, C++, Java, assembly|
|Operating system||Linux, AIX, Windows, macOS, z/OS, IBM i|
|Type||Java virtual machine|
|License||Apache 2 License|
Eclipse Public License 2.0
OpenJ9 can be built as a component of OpenJDK v8 and later, with prebuilt binaries available at the AdoptOpenJDK project for a number of platforms including Linux and Windows. OpenJ9 is also a core component of the IBM developer kit, which is embedded in many IBM middleware products, including WebSphere Application Server and Websphere Liberty. OpenJ9 is also a component of Open Liberty.
Extensive configuration options ensure that the JVM can be tuned to satisfy the requirements of a wide range of Java applications, from complex enterprise applications that run on mainframe hardware to short-lived applications that run on container-based cloud services.
OpenJ9 can trace its roots back to the ENVY/Smalltalk product developed by Object Technology International (OTI). IBM purchased OTI in 1996 for their Smalltalk expertise and products. However, when the Java language emerged as a leading language for the Enterprise market, the existing Smalltalk VM was adapted to process Java bytecodes instead. The name J9 evolved from the naming convention for the Smalltalk source code, K8. K->J (a backward step) because the developers believed that Smalltalk was better than Java, but 8->9 (a forward step) because the new VM would be better than before.
The J9 JVM became the runtime engine for many of IBMs Enterprise middleware products, where it has built its reputation for high performance, scalability, and reliability.
In 2017, J9 became an Eclipse Foundation project under the name Eclipse OpenJ9. IBM continue to be actively involved in the project and continue to put this Java VM at the core of many software offerings. At the Eclipse Foundation, OpenJ9 is classified as an incubator project, with the first release, v0.8.0, delivered in 2018.
The Eclipse OpenJ9 JVM is fully compliant with the Java JVM specification. The same version of the JVM can be used in OpenJDK 8 and later releases, which means that many features and improvements can be exploited by applications that run on different versions of Java.
Eclipse OpenJ9 embeds Eclipse OMR, which provides core runtime components that can be used to build runtime environments for different programming languages. At the OpenJ9 project, an extra layer of code adds the language semantics to provide a runtime environment for Java applications.
The components that make up Eclipse OpenJ9 are described in the following sections:
The Just-In-Time (JIT) improves the performance of Java applications by compiling platform-neutral Java bytecode into native machine code at run time. Not every method that gets called by an application is compiled. Instead, OpenJ9 records the number of times a method is called and triggers JIT compilation at a predefined threshold. The JIT compiler compiles methods at different optimization levels: cold, warm, hot, very hot (with profiling), or scorching. The hotter the optimization level, the better the expected performance, but the higher the cost in terms of CPU and memory. The higher optimization levels use special techniques such as escape analysis and partial redundancy elimination, or loop through certain optimization sequences more times. Although these techniques use more CPU and memory, the improved performance that is delivered by the optimizations can make the trade-off worthwhile.
Ahead of Time (AOT) compilation is a mechanism for improving start up performance. Methods are dynamically compiled into AOT code at runtime, which enables the JVM to start an application faster. AOT is enabled automatically when class data sharing is used (-Xshareclasses) and doesn’t require any special tuning. OpenJ9 automatically chooses which methods to compile based on heuristics that identify the start-up phase of large applications. For small or short running applications, the -Xtune:virtualized option should be added to get the most out of AOT-compiled code.
Class data sharing
Sharing class data between JVMs has two main benefits:
- Start up performance is improved by placing classes that an application needs when initializing into a shared classes cache.
- Memory footprint is reduced by sharing common classes between applications that run in separate Java VMs.
Unlike other class data sharing (CDS) implementations, enabling the feature in OpenJ9 requires only one step: setting -Xshareclasses on the command line when you start your application. When specified, OpenJ9 creates a memory mapped file to store and share the classes in memory. By default, OpenJ9 always shares both the bootstrap and application classes that are loaded by the default system class loader. Another benefit of the OpenJ9 CDS implementation is that the cache is updated dynamically. So when an application loads new classes, the JVM automatically stores them in the cache without any user intervention.
OpenJ9 also provides a public Helper API for integrating class sharing support into custom class loaders, plus several utilities for managing active caches.
To prevent applications running out of memory, objects in the Java heap that are no longer required must be reclaimed. This process is known as garbage collection (GC). OpenJ9 provides a number of garbage collection policies that are designed around different types of applications and workloads. Choosing the right policy depends on usage and performance goals. By default, OpenJ9 uses the Generational Concurrent (
-Xgcpolicy:gencon) policy, which is best suited to transactional applications that have many short lived objects. Alternative policies are available, including those that cater for applications with large Java heaps (
-Xgcpolicy:balanced), applications that are sensitive to response-time (
-Xgcpolicy:metronome), or applications that require high application throughput (
OpenJ9 contains extensive trace and debugging utilities to help identify, isolate and solve run time problems. Different types of diagnostic data are automatically produced by default when certain events occur, but can also be triggered from the command line. Types of data include:
Java dumps: These are produced when the JVM ends unexpectedly because of an operating system signal, OutOfMemoryError exception, or a user initiated keystroke combination. Java dumps summarize the state of the JVM when the event occurs, with most of the information relating to components of the JVM.
Heap dumps: Heap dumps show all the live objects on the Java heap when the JVM ends because of an OutOfMemoryError exception or when requested by a user. The information includes object address, type or class name, size, and references to other objects. Analyzing heap dumps might tell you which objects are using large amounts of memory on the Java heap and why these are not being garbage collected.
System dumps: Often known as core dumps, these are platform-specific and contain a raw binary dump of the process memory. This dump has a complete copy of the Java heap, including the contents of all Java objects in the application. OpenJ9 tools are available to process the system dump into a readable format for analysis.
Garbage collection data: To analyze garbage collection problems you can enable verbose logging, which provides data on all garbage collection operations including initialization, stop-the-world processing, finalization, reference processing, and allocation failures. For even more detailed analysis, you can turn on garbage collection tracing.
Trace data: The OpenJ9 trace facility can be used to trace applications, Java methods, or internal JVM operations with minimal impact on performance.
JIT data: If a general protection fault or abort event takes place, the JIT produces a small binary dump that can be analyzed by OpenJ9 developers to help determine the root cause.
Shared classes data: The shared classes data component provides some verbose options that can be used at runtime to show cache activity. The printStats and printAllStats utilities allow you to analyze the contents of a shared class cache.
The diagnostic component also includes the DTFJ application programming interface, which can be used to build diagnostic tools. DTFJ works with data from a system dump or a Java dump.
- AdoptOpenJDK: Community builds of OpenJDK with OpenJ9 are built and tested at the AdoptOpenJDK project.
- IBM: OpenJ9 is a component of the IBM SDK, Java Technology Edition, Version 8.
- Apache OpenWhisk: OpenWhisk is using OpenJ9 as the JVM for the Actions.
- Eclipse IDE: The Eclipse Foundation have approved the inclusion of OpenJDK 8 with OpenJ9 in the Eclipse Integrated Development Environment (IDE).
- Leonardo Zanivan (7 February 2018). "New Open Source JVM optimized for Cloud and Microservices". medium.
- Holger Voormann (14 March 2018). "Hello OpenJ9 on Windows, I Didn't Expect You So Soon!". DZone.
- David Rubinstein (20 September 2017). "IBM releases WebSphere Liberty code to open source". SD Times.
- Ronald Servant (18 September 2017). "How did the J9 in OpenJ9 get its name". medium.
- Dan Heidinga (6 June 2018). "Eclipse OpenJ9; not just any Java Virtual Machine". JAXenter.
- Monica Beckwith (1 March 2018). "Eclipse OpenJ9 - an Open Source Java Virtual Machine Based on the Eclipse OMR Project". InfoQ.
- Ben Corrie (6 June 2018). "Class sharing in Eclipse OpenJ9". IBM developerWorks.
- Parameswaran Selvam (9 March 2018). "Apache OpenWhisk Java actions on Eclipse OpenJ9 Runtime". medium.