I have a application that during idle times usually only needs 1GB of RAM however when I launch it inside in docker, then it shows much higher RAM usage (5GB) from the outside.
The JVM metric show that I still only use ~1GB of RAM, but the JVM does not really release any RAM it ever claimed.
I cannot reduce the RAM limits (~8GB using MaxRamPercentage), as it needs it during high load, startup, and some special events. I could periodically call System.gc()
as that frees and releases a lot of memory, but the RAM shoots back up to where it was after a few requests. This claiming of unused RAM wastes a lot of resources and causes OOMs on the server as none of the applications release their memory.
According to this JEP-346 the "bug" has been fixed, that caused the garbage collector to not release the memory, but I don't see any improvements.
For testing purposes, I also tried using the -XX: UseShenandoahGC
and it releases the memory as expected. But during startup it takes almost all the RAM which causes issues during server/multiple simultaneous application restarts.
TLDR: Actually used RAM ~1 GB, claimed RAM ~5 GB, RAM Limit ~8GB. The default GC does not release enough RAM, without explicitly calling System.gc(). Is the G1 GC the default GC in Java 17? (AFAICT it is) Are there any parameters required to make the changes from JEP-346 work as expected?
CodePudding user response:
I think this is similar question to what you are asking.
As it is pointed in the comments to the question this feature is opt-in and can be enabled using parameters described in the JEP 346 Documentation.
Both -XX:G1PeriodicGCInterval
and -XX:G1PeriodicGCSystemLoadThreshold
have to be set to a value greater than default 0 for the functionality to work.