Running a JVM in a Container Without Getting Killed
Starting in JDK 9, and earlier if you use JDK 8u131, your JVM can detect how much memory is available when running inside a Docker container.
Join the DZone community and get the full member experience.
Join For FreeNo pun intended.
The JDK 8u131 has backported a nice feature in JDK 9, which is the ability of the JVM to detect how much memory is available when running inside a Docker container.
I have talked multiple times about the problems running a JVM inside a container, how it will default in most cases to a max heap of 1/4 of the host memory, not the container.
For example, in my machine:
$ docker run -m 100MB openjdk:8u121 java -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 444.50M
Ergonomics Machine Class: server
Using VM: OpenJDK 64-Bit Server VM
Wait, WAT? I set a container memory of 100MB and my JVM sets a max heap of 444M ? It is very likely that it is going to cause the kernel to kill my JVM at some point.
Let’s try the JDK 8u131 with the experimental option -XX:+UseCGroupMemoryLimitForHeap
$ docker run -m 100MB openjdk:8u131 java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 44.50M
Ergonomics Machine Class: server
Using VM: OpenJDK 64-Bit Server VM
Ok, this makes more sense. The JVM was able to detect the container has only 100MB and set the max heap to 44M.
Let’s try in a bigger container:
$ docker run -m 1GB openjdk:8u131 java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 228.00M
Ergonomics Machine Class: server
Using VM: OpenJDK 64-Bit Server VM
Mmm, now the container has 1GB, but the JVM is only using 228M as the max heap. Can we optimize this even more, given that nothing else other than the JVM is running in the container? Yes, we can!
$ docker run -m 1GB openjdk:8u131 java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 910.50M
Ergonomics Machine Class: server
Using VM: OpenJDK 64-Bit Server VM
Using -XX:MaxRAMFraction
, we are telling the JVM to use available memory/MaxRAMFraction as the max heap. Using -XX:MaxRAMFraction=1
, we are using almost all the available memory as the max heap.
Published at DZone with permission of Carlos Sanchez, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments