4

I have a Springboot application with Mule running inside a docker container as a micro service. It takes about 700MB even when it is idle. It is noticed that JVM has allocated heap of 380 MB which is max heap provided using -Xmx parameter. Though max heap is allocated, the micro service only use about 50 MB when idle. The question is how to released unused memory back from JVM.

It seems that reducing MaxHeapFreeRatio we can ask JVM to shrink when there is more free memory ratio. However MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 did not make much difference and JVM did not release memory. But when I use -Xmn with above two parameters JVM releases heap memory as expected. See below image for example scenario.

Java version 8

-Xmn100M  -XX:+PrintGCDetails  -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -Xmx384M

enter image description here

  1. Why does MinHeapFreeRatio and MaxHeapFreeRatio does not work as expected?
  2. If above parameters are fine what are the consequences of -Xmn and what is the value of it should be?
  3. What are other solutions in order to achieve the task of releasing memory back from JVM?
Community
  • 1
  • 1
Udara S.S Liyanage
  • 6,189
  • 9
  • 33
  • 34
  • This is a very valid question that I also share. It's not just "a few MB". A lot of Java applications have a pattern where some time during their lifecycle they need a big spike in memory for a big job which can be several GB and then they never use that amount of memory again, and since the memory is never released to the OS it's a big big waste. – Chin May 17 '18 at 13:50

2 Answers2

3

First, this should really be a comment, but it's going to be way to big probably. Question yourself if you really REALLY want to release memory from JVM back to the OS. Acquiring it back will be expensive, like probably more expensive then running your application as it is - it will slow you down.

Then, your default collector under java-8 is Parallel GC, I am not very sure that those MinHeapFreeRatio and MaxHeapFreeRatio actually work with it. I have tried with G1GC - and it does, but did not with Parallel. Then adding the -Xmn might have been just luck/good timing; AFAIK it should not impact the other two parameters. this is a rather interesting answer to a similar question that you have.

Community
  • 1
  • 1
Eugene
  • 117,005
  • 15
  • 201
  • 306
  • No, it won't be more expensive, in fact it's quite the contrary. Imagine that you have a process that uses a few Gb of memory (which is so easy with Java considering how memory hungry that thing is). Now, you fork that process and allocate another few Gb. After awhile, a lot of that ends up being disposed, but since it's still allocated from the OS' perspective, eventually you run out of memory and you start paging, those I/O will cost you a LOT more than re-allocating memory. – E.T Mar 25 '22 at 17:16
0

What are other solutions in order to achieve the task of releasing memory back from JVM?

Not sure if you have tried OpenJ9 yet. It has a tuning mechanism to detect when the JVM is idle and release free memory back pages to OS. This article talks about the idle tuning feature.

You can get OpenJDK-OpenJ9 binary from adoptopenjdk.

In case you stick to OpenJDK-Hotspot combination, you can try exploring –XX:-ShrinkHeapInSteps option which is expected to shrink the heap aggressively, but I am not sure which GC policies it works with.

Ashutosh
  • 181
  • 5