Now available! Red Hat OpenShift Container Platform for Linux on IBM Z and LinuxONE Learn more

Hands-on with OpenJ9 benefits for Spring applications

Overview

The Eclipse OpenJ9 JVM offers Spring applications significant benefits when deployed as part of a cloud-native runtime. OpenJ9 comes with improvements to memory overhead and startup times, achieved through shared classes and an aggressive focus on memory footprint.

To benefit from the startup time improvements, enable OpenJ9’s SharedClasses Cache (which enables dynamicAOT), by setting the following JVM options:

-Xshareclasses -Xscmx50M -Xquickstart

Hands on exploration of benefits

To explore these memory overhead and startup times benefits yourself, you can run Spring’s petclinic demo, using Docker to test with OpenJDK and OpenJ9, enabling you to see for yourself the differences between the two runtimes. We’ve supplied a collection of Dockerfiles to make this really simple to do.

Memory footprint

You can check the memory footprint for the petclinic app by following these steps:

  1. Get the Dockerfiles.

  2. Build each of the docker images:

    docker build -f Dockerfile.openj9 -t=demo.openj9
    docker build -f Dockerfile.openjdk -t=demo.openjdk
    
  3. From a spare command prompt, run the OpenJ9 image, and note the startup time:

    docker run --rm -it demo.openj9
    
  4. From another spare command prompt, run the OpenJDK image, and note the startup time:

    docker run --rm -it demo.openjdk
    
  5. Finally, from another command prompty, run:

    docker stats
    
  6. Clean up:

    docker ps
    docker kill <id>
    

Here’s the output from docker stats, showing OpenJ9 (af0c33faf180, on the first line) using only around 1/3 of the memory that OpenJDK uses when running Spring’s petclinic sample application:

CONTAINER ID     NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
af0c33faf180     serene_tereshkova   0.95%               153.7MiB / 1.952GiB   7.69%               718B / 0B           85.3MB / 4.1kB      42
8abb2874bed9     pedantic_darwin     0.65%               469.2MiB / 1.952GiB   23.48%              718B / 0B           80.7MB / 0B         36

Memory footprint has always been a focus for the OpenJ9 JVM, and there are a lot of reasons why OpenJ9 is smaller:

  • Size of the class meta data
  • Smaller default heap sizes
  • Less aggressive Java heap expansion
  • An overall consistent focus during development on retaining a small memory footprint.

Startup time

You can check the startup times for the petclinic app by following these steps:

  1. Get the Dockerfiles.

  2. Build the docker image:

    docker build -f Dockerfile.openj9.cold -t=demo.openj9.cold
    
  3. Launch the docker image:

    docker run --rm -it demo.openj9.cold
    

    This image has sharedclasses enabled so that OpenJ9’s class meta data (J9ROMClass) can be saved in the cache as well as AOT & JIT hints.

    The startup will typically be slower in the “cold” run, as the cache is being filled.

  4. Build the new image with the cache filled.

  5. Save the last image using:

    docker commit <id> demo.openj9.warm
    
  6. Run the image with the cache filled:

    docker run --rm -it demo.openj9.warm
    

The footprint should be equivalent to the earlier runs, but with a faster startup. This is mostly due to AOT relocation being much faster than JIT compilation (in the order of 10-100x).

Ozzy Osborne