Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 to Java 17 migration causing significant memory increase in Docker container

Could you kindly help us with a query we have regarding a Java 8 Spring boot application running in Docker containers in ECS? After migrating to Java 17, we observed a significant 1GB increase in memory usage of the container as compared to the memory usage of the container running on Java 8 (we compared the memory using the docker stats command for both the containers). We only have the Java process running inside the container. The jmap command output from both Java 8 and Java 17 are provided below. The only significant changes we observed are that:

  1. The Garbage collection algorithm is G1, which is now the default in Java 17, as compared to CMS in Java 8.
  2. The MaxNewSize has increased from 166.375MB in Java 8 to 1228.0MB in Java 17.

We would like to know if this is the reason for the increased memory usage in the Docker container. We understand that the new G1 garbage collection algorithm has slightly higher memory usage (around 120 MB, as compared to 12 MB for CMS, as found from the jcmd VM.native_memory command output), but we were not expecting such a drastic increase. Any suggestions or insights on this issue would be greatly appreciated.

jmap output for Java 8

using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 2147483648 (2048.0MB)
   NewSize                  = 174456832 (166.375MB)
   MaxNewSize               = 174456832 (166.375MB)
   OldSize                  = 1973026816 (1881.625MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 157024256 (149.75MB)
   used     = 135629568 (129.346435546875MB)
   free     = 21394688 (20.403564453125MB)
   86.37491522328881% used
Eden Space:
   capacity = 139591680 (133.125MB)
   used     = 131489752 (125.39839935302734MB)
   free     = 8101928 (7.726600646972656MB)
   94.19598073466842% used
From Space:
   capacity = 17432576 (16.625MB)
   used     = 4139816 (3.9480361938476562MB)
   free     = 13292760 (12.676963806152344MB)
   23.747586128406954% used
To Space:
   capacity = 17432576 (16.625MB)
   used     = 0 (0.0MB)
   free     = 17432576 (16.625MB)
   0.0% used
concurrent mark-sweep generation:
   capacity = 1973026816 (1881.625MB)
   used     = 73134816 (69.74679565429688MB)
   free     = 1899892000 (1811.8782043457031MB)
   3.706731981893144% used

38981 interned Strings occupying 3969216 bytes.

jmap output for Java 17

using thread-local object allocation.
Garbage-First (G1) GC with 2 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 2147483648 (2048.0MB)
   NewSize                  = 1363144 (1.2999954223632812MB)
   MaxNewSize               = 1287651328 (1228.0MB)
   OldSize                  = 5452592 (5.1999969482421875MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 1048576 (1.0MB)

Heap Usage:
G1 Heap:
   regions  = 2048
   capacity = 2147483648 (2048.0MB)
   used     = 1115684864 (1064.0MB)
   free     = 1031798784 (984.0MB)
   51.953125% used
G1 Young Generation:
Eden Space:
   regions  = 977
   capacity = 1312817152 (1252.0MB)
   used     = 1024458752 (977.0MB)
   free     = 288358400 (275.0MB)
   78.03514376996804% used
Survivor Space:
   regions  = 38
   capacity = 39845888 (38.0MB)
   used     = 39845888 (38.0MB)
   free     = 0 (0.0MB)
   100.0% used
G1 Old Generation:
   regions  = 50
   capacity = 794820608 (758.0MB)
   used     = 50331648 (48.0MB)
   free     = 744488960 (710.0MB)
   6.332453825857519% used

43272 interned Strings occupying 4300576 bytes. 

JVM options used for Java 8:

-server -Xms2048m -Xmx2048m -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails

JVM options for Java 17:

-server -Xms2048m -Xmx2048m -XX:+UseG1GC -Xlog:gc*
like image 724
Rohan Bhattacharya Avatar asked Apr 08 '26 13:04

Rohan Bhattacharya


1 Answers

We are facing the same Problem. The Docker Images have doubled there memory consumption after switching from JDK11 to JDK 17.

Our "old" JDK 11 was with OpenJ9 VM

FROM adoptopenjdk/openjdk12-openj9

and we switched to

FROM eclipse-temurin:17-jdk

The Eclipse-Temurin uses the hotspot vm instead of openj9. After switching to a JDK 17 with OpenJ9 the Problems are gone.

We now use

FROM ibm-semeru-runtimes:open-17-jdk-focal (which has OpenJ9 VM as default)

and it works like expected.

like image 171
user2718047 Avatar answered Apr 11 '26 15:04

user2718047



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!