Why is my java process taking more memory than I gave it?
It seems to be quite common misconseption that the memory you give to java process with -Xmx and -Xms command line arguments is the amount of memory the process will consume but in fact that is only the amount of memory your java object heap will have. The heap is just one factor in how much memory the java process will consume. To better understand how much memory your java application will consume from the system you need to understand all the factors that account for the memory usage. Those factors are:
- Objects
- Classes
- Threads
- Native data structures
- Native code
The memory consumption associated with each item varies across applications, runtime environments and platforms. So how do you calculate the total memory? Well, it’s not really all that easy to get accurate number because you have little control over the native part. The only parts you can really control is the amount of heap -Xmx, memory consumed by classes -XX:MaxPermSize and thread stack -Xss which controls the amount of memory each thread takes. Be careful when adjusting stack size as too low size will cause StackOverflow exceptions and your application won’t work correctly. So the formula is:
(-Xmx) + (-XX:MaxPermSize) + numberofthreads * (-Xss) + Other mem
The other mem part depends on how much native code is used like NIO, socket buffers, JNI etc. It’s anywhere from 5% of total jvm memory and up. So assume we have following JVM arguments and 100 threads
-Xmx1024m -XX:MaxPermSize=256m -Xss512k
That would mean that the jvm process would take at least: 1024m + 256m + 100*512k + (0.05 * 1330m) = 1396.5m.
I usually use a quick approximation rule of 1.5 * max heap to be the minimum amont of RAM a tomcat process will require. This can be higher if you have large application that requires you to increase MaxPermSize beyond 256m. If you use this to size how much memory your system will require remember that you need to leave memory for the OS and other applications running on the system otherwise you might end up using a lot of virtual memory that will affect your application performance negatively.