1

I have a Tomcat server running a single REST web service application.

I've created a test web service returning memory usage obtained by

Runtime.getRuntime().totalMemory().

According to javadoc it should return "total amount of memory in the Java virtual machine". The number is 110MB (Runtime#maxMemory() returned 256MB).

I have also looked at htop to see how much memory is java actually consuming, and found out it's 421MB.

There is only one /usr/bin/java process running, no other Java applications are present - so I assume that's the one and only JVM instance on the server, and it's total memory usage should be correctly returned by Runtime#totalMemory(). I don't understand why that's not the case, unless the javadoc is somehow misleading or there's something else I'm missing.

UPDATE

So Runtime#totalMemory() returns just the heap size, that makes sense (although I still think the javadoc should make that clearer).

According to How is the java memory pool divided? the non-heap space consists (mainly) of PermGen and code cache.

According to https://dzone.com/articles/java-8-permgen-metaspace PermGen space has been removed in Java 8 (which is what I'm using) and has been replaced with Metaspace. I got the Metaspace settings of the JVM with the command:

java -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal 2>&1 |grep Metaspace

and found out that MaxMetaspaceSize is unlimited by default (Tomcat doesn't override this setting). It's possible that it has grown over time then.

In short, I expected the java process memory usage to be somewhat larger than the heap size, but not almost 4x larger.

Community
  • 1
  • 1
Cinnam
  • 1,892
  • 1
  • 15
  • 23
  • Doesn't `totalMemory()` only return the total heap memory? There are plenty of non-heap structures required for a JVM. – biziclop Sep 10 '15 at 14:17
  • See http://stackoverflow.com/questions/3571203/what-is-the-exact-meaning-of-runtime-getruntime-totalmemory-and-freememory – Austin Sep 10 '15 at 14:17
  • @biziclop I have updated my question. – Cinnam Sep 10 '15 at 14:57
  • There are loads of shared libraries and per thread structures (thread metadata, stacks). With a small heap those will take up the majority of the overall memory. But if you've got a heap of 8-16G, their share will be negligible. You can try enabling [Native Memory Tracking](https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html) to get a more detailed view of what exactly is going on. – biziclop Sep 10 '15 at 15:00
  • @biziclop Thanks, I'll try that. – Cinnam Sep 10 '15 at 15:11

0 Answers0