Initial amount of memory to run a Spring Boot application

Carlos Alberto picture Carlos Alberto · Feb 12, 2016 · Viewed 14k times · Source

Is there any initial amount of memory I should set to run a Spring Boot application?

For example, to run a embedded Tomcat/Undertow application we could set a typical amount of memory for -Xms and -Xmx java options.

How can I find out which values I need to set for running my application?

Answer

pczeus picture pczeus · Feb 12, 2016

You should run the JavaMissionControl or another Profiler to see your actual memory requirements. You can run the JavaMissionControl on the server where Java is installed (and in the path) by running 'jmc' from a command prompt, then attaching to your local JVM. You can attach to a remote JVM as well. For more information, refer to this link: http://www.oracle.com/technetwork/java/javaseproducts/mission-control/index.html

Typically what I do is set the max memory higher than needed, max = 1GB seems like a good starting point. You will want to watch the memory profile of your application over a period of typical activity. Realize that when you set an initial heap size of 64mb, the garbage collector is running a scheme that will not start a major garbage collection until necessary for performance reasons (garbage collection is expensive). As a result, you will see the memory creep up over time to around 80% of the heap size (this % is adjustable). Once the threshold is reached, garbage collection kicks in and you will see the used JVM memory drop very low again.

Normally what I am looking for is the level of memory that is in use consistently after a series of major garbage collections. So let's say after running your application you see that the solid state memory usage after a major garbage collection consistently drops to around 40Mb. Therefore, I typically will then set the min JVM size to around this amount, since I know I always need at least that much as a minimum.

Now you know a decent starting point for your minimum requirement, so what would be the maximum memory needed? Well, this takes a little more profiling and trial and error. What I do is begin to reduce the maximum memory setting lower and profile for a while. What you are looking for is the frequency of major garbage collections and the JVM CPU utilization reaching consistently high values.

I would continually reduce the memory until I see major garbage collection happening several times in a short period of time under a load and the CPU spike up during these periods of garbage collection. Once I see this behavior, I then slowly increase the max memory until that behavior stops, to find the sweet spot of max memory needed.

This is a very simple way to find reasonable values for min/max memory settings, and works very well for me in most common application scenarios. There are of course many other more exhaustive ways to profile your application to fine tune both the memory setting and garbage collection schemes/settings if you really want to fine tune your requirements.