5

Historically, HotSpot had poor record running in docker containers misjudging the resources allocated (for example RAM). However, things are slowly improving.

How is OpenJ9 aligned with docker containers and to what extent it is aware of the container-provided resources (memory, sockets, threads, etc.)

Also, during the JavaOne 2017 presentation it was mentioned that OpenJ9 can cache jit-compiled classes across different OpenJ9 VMs. Is this shared cache possible when the VMs are confined to different containers (or) if the containerized JVMs share a docker volume?

ch271828n
  • 15,854
  • 5
  • 53
  • 88
Hristo Stoyanov
  • 1,508
  • 3
  • 15
  • 24

2 Answers2

2
  1. Container support is currently being worked on, for cgroup awareness, please check this PR. This will lead upto adding container support as well.
  2. With regards to the Shared Class Cache (SCC), both scenarios are possible. Please see "Using the Class Data Sharing feature" from here for an example of sharing a docker volume. When the JVMs are confined to different containers with no shared volume, it is recommended to build the docker container with the SCC pre-built. You dockerfile will look like this.

    FROM adoptopenjdk/openjdk9-openj9:x86_64-alpine-jdk-9.181

    RUN mkdir /opt/shareclasses && mkdir /opt/app

    COPY japp.jar /opt/app

    CMD ["java", "-Xshareclasses:cacheDir=/opt/shareclasses", "-jar", "/opt/app/japp.jar"]

You would then need to build and run the image and commit the resultant container and make that as your base image.

docker build -t japp:latest . docker run japp docker commit container_id japp

dino
  • 181
  • 1
  • 4
0

It is possible to create a Shared classes cache and include it in the Docker file.

The Shared classs cache can be created in a dev or pre-prod environment, or while runing some tests on the application. Creating the cache in Pre-prod might be more effective, but dooing it with tests during the build process is much simpler. I tested it with a Spring Boot application, and even the simple "contextLoads" test which is included with any newly generated Spring Boot project makes a huge difference.

Here is an example with tests using Maven, but the same VM options can be used in different scenarios as well.

1. Running tests with shared classes cache enabled:

You can do it in Maven with the Surefire plugin, I'm not sure how can this be done with Gradle

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <argLine>-Xquickstart -Xshareclasses:cacheDir=classCache,name=appname -Xscmx32m </argLine>
  </configuration>
</plugin>

VM Arguments: -Xquickstart -Xshareclasses:cacheDir=classCache,name=appname -Xscmx32m

  • The cacheDir sub option is there to specify the cache folder to make it easier to include in the Docker image
  • The name sub option is there to avoid the hardly predictable automatic cache name
  • -Xscmx option is there to limit the cache size, this should be tuned for the application, there is a tradeoff between startup speed and image size
  • -Xquickstart option instructs the JVM to do as much AOT as possible when used combined with the -Xshareclasses option

You can check how much of the cache size is used with the printStats subOption like this: java -jar -Xshareclasses:cacheDir=classCache,name=appname,readonly,printStats application.jar

2. Add prewarmed cache to the Docker image

Simply add the directory set by the cacheDir sub option to the image in this case classCache

ADD classCache classCache

Since these files will change every single time, classCache should be added last to the image

And run the application with the cache

ENTRYPOINT exec java -Xquickstart -Xtune:virtualized -Xshareclasses:cacheDir=classCache,name=appname,readonly -jar application.jar

VM Arguments: -Xquickstart -Xtune:virtualized -Xshareclasses:cacheDir=classCache,name=appname,readonly -jar application.jar

The cache can be specified with the classCache and name sub options, without these the JVM might create a new cache folder and ignore the one added to the image.

According to my experience the readonly option makes it a bit faster, but it's not strictly necessary. Since this cache will be dropped when the container is destroyed it's not necessary to persist the canges.

-Xquickstart and -Xtune:virtualized options are there to further optimize startup speed in the container

Pusker György
  • 398
  • 1
  • 11