Search code examples
tomcathtop

htop reporting Tomcat 8.5 as consuming 4GB when I've set -Xmx1024M


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:

enter image description here

Why is then htop reporting my Tomcat as consuming half of my 8 GB memory?

enter image description here


Solution

  • 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:

    1. PermGen
    2. Thread stacks
    3. Native code compiled by the JIT

    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.