I have configured my Tomcat instance to not use more than 1GB of RAM by setting the following in setenv.sh
:
$ cat /opt/tomcat8.5/bin/setenv.sh
#!/bin/sh
export JAVA_OPTS="-Djava.awt.headless=true -server -Xms48m -Xmx1024M -XX:MaxPermSize=512m"
Indeed, this appears to be taken into account by the running Tomcat instance:
$ ps aux | grep -i tomcat-juli.jar | grep -v grep | awk '{print $2}'
26105
$ sudo jinfo 26105 | grep VM\ flagsNon-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=50331648 -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=357564416 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=16777216 -XX:OldSize=33554432 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC
And by attaching to the running instance using Java VisualVM, I see a picture compatible with the above:
Why is then htop
reporting my Tomcat as consuming half of my 8 GB memory?
Limiting the heap size (-Xmx1024M
) only limits the size of the Java heap. The JVM is free to use as much "native" memory as it feels is necessary in order to run itself.
Things that aren't part of the Java heap:
Have a look at Java native memory usage to see how you can get some insight into what memory is being used outside the Java heap.
Note that if you are willing to give your JVM a whole gig or RAM, you may as well set -Xms
== -Xmx
, otherwise you will just waste CPU cycles re-sizing memory at intervals until the heap reaches its maximum size.