- Use -Xmx to specify the maximum heap size
- Use -Xms to specify the initial Java heap size
- Use -Xss to set the Java thread stack size, can be easily skipped
My strong suggestion would be to keep Xmx and Xms values the same as it will optimize memory initialization. As it is currently if you monitor the GC data closely, you will notice that is a relatively short period of time (usually less than an hour), the JVM will eventually increase the heap size to the -Xmx setting. Each time the JVM increases the heap size it must ask the OS for additional memory, which takes time (and thus adds to the response time of any requests that were is process when the GC hit). And, usually, the JVM will never let go of that memory. Therefore, since the JVM will eventually grab the -Xmx memory, you might as well set it to that at the beginning.
Another point is that with a smaller heap size (starting with -Xms), GCs will happen more often. So by starting with a larger heap initially the GCs will happen not as often.
You can start with those parameters and adjust them as needed. Test often, sometimes Java programs won't run unless you will have a certain amount of memory for them to use...
You can also adjust memory limits of Docker containers, but then we will reach to risky areas. Java, generally speaking, have no clue about your soft-limits of the docker container. There is some work in OpenJDK community to address this, but as far as I know by this time it is still unstable and planned for JDK10 - not sure if they will maintain backward compatibility.
Now, with Java, it all depends on how the app is initialized and maintain. A very interesting analysis on that you can find
here. I will admit I had no time to dig into that, but - in general - what I wrote above is your starting point anyway.
One last thing - it is quite a good idea to experiment with GC config as well AND monitor both GC and memory consumption. For the first I would suggest trying out G1GC with JVM 8 - it might, but not for sure, bring you some optimizations. More details
here. For monitoring, any tool that will support remote JMX will do, i.e. DataDog or Prometheus. That will give you an insight into the actual use of the memory, etc.
Hope it helps...