Skip to content

Compare OpenJ9 and HotSpot memory & CPU usage with Docker

License

Notifications You must be signed in to change notification settings

ksilz/bpf-talks-openj9-memory

Repository files navigation

Eclipse OpenJ9: Memory Diet for Your JVM Applications

What Is This?

Eclipse OpenJ9 is a Java Virtual Machine (JVM) that uses less container memory and therefore achieves lower cost. It's mostly a drop-in replacement for the standard Oracle HotSpot JVM.

I demonstrated the memory savings in a lightning talk to the London Java Community (LJC) on May 1, 2020. Please read the slides first! My detailed results are in an Excel file.

Why Should I Believe You?

You shouldn't believe everything you read on the Internet. Granted, I'm a full-stack developer with 21 years of Java experience. And I think of myself as trustworthy. But don't we all?!

That's why you can run OpenJ9 against HotSpot yourselves. And you can tweak them — change the Java options or build a whole new container image!

And now for some shameless self-promotion. I write a blog about how to get better Java projects faster with JHipster and Docker. It's been dormant since the end of 2019, but I'll pick it up again by June 2020. Spoiler alert: I'll also write about Flutter, Google's cross-platform UI toolkit for native mobile, web & desktop apps. I built a mobile prototype with it last year.

What Do I Need to Test OpenJ9 and Hotspot Myself?

You need Docker & Docker Compose. I used two different applications to test OpenJ9 vs HotSpot:

Both applications use the most recent Java 8 and 11 versions from AdoptOpenJDK, as of April 2020.

The containers are limited to 2 GB RAM and 2 CPUs. So I recommend at least 8 GB of RAM and 4 CPU cores to run these applications on your test machine.

How Do I Run OpenJ9 and HotSpot Myself?

Each application has four different Docker Compose Files in the root directory of this repository:

JVM Type JVM Version Web application Benchmarks
HotSpot 8 docker-compose-web-app-hotspot-8.yml docker-compose-benchmark-hotspot-8.yml
HotSpot 11 docker-compose-web-app-hotspot-11.yml docker-compose-benchmark-hotspot-11.yml
OpenJ9 8 docker-compose-web-app-openj9-8.yml docker-compose-benchmark-openj9-8.yml
OpenJ9 11 docker-compose-web-app-openj9-11.yml docker-compose-benchmark-openj9-11.yml

So here's how you run the web application with HotSpot 11:

docker-compose -f docker-compose-web-app-hotspot-11.yml up

And this is how you run the benchmarks with OpenJ9 8:

docker-compose -f docker-compose-benchmark-openj9-8.yml up

When the benchmarks are done, the container stops. That's why I used the time command on the Mac to measure how much CPU time they took:

time docker-compose -f docker-compose-benchmark-openj9-8.yml up

[...]

benchmark-openj9-8 exited with code 0
docker-compose -f docker-compose-benchmark-openj9-8.yml up  0.73s user 0.12s system 0% cpu 7:50.92 total

The web application runs until you manually stop the container. So I only took the time that Spring Boot self-reports in the log:

Started SimpleShopApp in 18.302 seconds (JVM running for 19.362)

I used the second number in my slides: JVM running for 19.362

For both applications, I monitored CPU & memory utilization with docker stats:

docker stats --format "{{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}"

This command produces tab-separated output. You can redirect that to a file and then import into a spreadsheet. I did: The benchmark data is in this folder as data-benchmark-*.txt. The log output of the benchmark runs is in the same folder as output-benchmark-*.txt

How Do I Tweak OpenJ9 and HotSpot?

You can tweak both the Java options and the CPUs and memory of the container right in the Docker Compose files. For example, here's the Docker Compose file for running the benchmark in OpenJ9:

version: '2.2'

services:
  benchmark-openj9-8:
    image: 'joedata/bpf-talks-openj9-memory-benchmark:openj9-8'
    container_name: benchmark-openj9-8
    environment:
      - >-
        JAVA_OPTS=-Xmx1024m -Xms256m -Xtune:virtualized
      - BENCHMARKS=-r 5 gauss-mix,movie-lens,akka-uct,fj-kmeans,mnemonics,scala-doku,finagle-chirper
    cpus: 2.0
    mem_limit: 2147483648

You can change the Java options in the JAVA_OPTS line. Which Java options can you use?

The number of CPUs is in the cpus: line, and the memory in the mem_limit one (in Bytes).

For the benchmark only, you can tweak the BENCHMARKS line. The number of repetitions is 5 here (-r 5). The comma-separated list of benchmarks follows right afterwards. The complete list of benchmarks is on the Rennaissance Suite web site. Please note that some of them actually crashed in my environment.

How Can I Change the Java Version?

You can't through the Docker Compose files. I build all the Docker images myself, so the Java version is hard-coded in there. If you want a different version of Java, you need to build the Docker images yourself.

I used the "Debian Slim JRE" images from AdoptOpenJDK as my base images. Here are their Docker Hub repositories:

You can find my Docker Images on Docker Hub, too:

How Do I Build the Benchmark Docker Image?

  • Change into the src/benchmark folder.
  • This folder has 4 Dockerfile: HotSpot and OpenJ9, Java 8 and Java 11. I'm sure you can tell them apart by their names! 😉
  • Download version 0.10.0 of the Renaissance Suite JAR file from the web site and save it in this folder. It's huge: 415 MB.
  • There's an MD5 checksum in the folder so you can test if the JAR file is ok:
md5sum --check renaissance-mit-0.10.0.jar.md5
  • Edit the first line of the Dockerfile you want to change to the new Java Docker image. Here's that line for OpenJ9 8:
FROM adoptopenjdk/openjdk8-openj9:x86_64-debianslim-jre8u252-b09_openj9-0.20.0
  • Now build the Docker image by running a docker build in this directory. Here's how you build the OpenJ9 8 image. Please note that I didn't specify a Docker repository here (before the image name):
docker build -t my-memory-benchmark:openj9-8-new -f Dockerfile-openj9-8 .
  • As the last step, update the Docker Compose file to use your new image. That's the image: line in there. For the sample image that you just built in the line above, your Docker Compose file would have this image: line:
    image: 'my-memory-benchmark:openj9-8-new'

How Do I Build the Web Application Docker Image?

md5sum --check simple-shop-1.0.0.jar.md5
  • Now you can edit the Dockerfile, build it and use it in you Docker Compose files the same way as described in the previous section.

Releases

No releases published

Packages

No packages published

Languages