everyone,
some weeks ago we changed our background application from Oracle Java 8 to the Adopt JDK 11 (Hotspot). We didn't notice anything in the first weeks and months, but now an update from our data center is pending. In the test system we noticed that there is a memory problem.
We have up to 30 instances of our application running on one server. Each one runs with the Tanuiksoft Service Wrapper and has been allocated different amounts of XMX memory depending on the instance.
Every 10 minutes our service prints the following information
double total = Runtime.getRuntime().totalMemory() / 1024;
double max = Runtime.getRuntime().maxMemory() / 1024;
double free = Runtime.getRuntime().freeMemory() / 1024;
int activeThreads = Thread.activeCount();
logger.info("Memory: [total={0}] [max={1}] [free={2}] [active threads={3}]", //
total, max, free, activeThreads);
This is the output from Java 8 where total memory reduces.
If I understand this correctly, the totalMemory is the one the VM lets the operating system reserve - this memory is then no longer available to the operating system. Max memory is understood to be the XMX parameter in the service wrapper. freeMemory is the memory which is still free from the totalMemory.
At that time the output looked like this
Memory: [total=278,016] [max=466,432] [free=183,895] [active threads=33]
Memory: [total=278,016] [max=466,432] [free=176,264] [active threads=33]
Memory: [total=259,072] [max=466,432] [free=132,683] [active threads=33]
Memory: [total=259,072] [max=466,432] [free=125,653] [active threads=33]
Memory: [total=259,072] [max=466,432] [free=118,370] [active threads=33]
You can see that the total memory has been released again. Today with Java 11 it looks like this:
Memory: [total=451,584] [max=524,288] [free=124,309] [active threads=33]
Memory: [total=451,584] [max=524,288] [free=338,183] [active threads=33]
Why doesn't the VM release the memory. It has reserved 451 MB, of which 340 MB are still free. So it would make sense to free the memory again, wouldn't it? The service does not do any further actions until the next restart, so that the memory also goes up and down only minimally. Until the restart (several hours later), the free memory remains at about 300 MB. With Java 8, we have never seen this.
Since some services need a lot of memory at peak times, but it is very unlikely that all services need a lot of memory at the same time, we could live very well with the fact that the sum of all XMX values on the server was always larger than the physical memory. Due to the Java 11 conversion we now have a problem here.
We have also entered the following parameters in the wrapper.conf:
wrapper.java.additional.1=-Xmx512m
wrapper.java.additional.2=-Xms16m
wrapper.java.additional.3=-XX:MaxPermSize=256M
wrapper.java.additional.4=-XX:GCTimeRatio=19
wrapper.java.additional.5=-XX:MinHeapFreeRatio=20
wrapper.java.additional.6=-XX:MaxHeapFreeRatio=30
wrapper.java.additional.7=-XX:-ShrinkHeapInSteps
wrapper.java.additional.8=-Xlog:gc+ergo*=info
wrapper.java.additional.9=-XX:+UseG1GC
We have the same problem with non computing center customers, but they don't notice it so much, because there are only a few instances running and the memory is high enough. In the datacenter the memory is unfortunately somewhat limited.
Does anyone have any idea what we can set here to free the memory?