The memory reported in the System Monitor is all memory used by the process, not just Java heap. This memory includes the:
- Executable files of the VM itself, and the libraries it has loaded
- Working space for the VM as a process for use in such things as the Hotspot compiler, GC, IO buffers, screen and graphic buffers, reading VM files and the like
- Java Heap and other reportable memory structures
In your case, 10MB of the process is being used to store the Java stack and the Java objects. The other 90MB is the Java program itself and the memory internal to the VM.
That's the short answer, but there is one other important consideration - Java can (and does) free excess heap back to the OS. This is controlled by the -XX:MinHeapFreeRatio
and -XX:MaxHeapFreeRatio
flags. By default the MaxHeapFreeRatio is 70% - which is almost exactly what is shown in your Heap graph (the saw tooth pattern from 6MB to a bit under 10MB). If your app had a significantly larger drop, you would see a (small) saw tooth pattern for the Java process in the System Monitor.
For performance, you should generally allow the JVM to keep hold of a significant chunk of the heap freed from a GC. Why? Because we know that the JVM will immediately need to start allocating memory again and it's more efficient for the process (and the OS) for Java to keep this.
So, in summary:
- The System Monitor shows the memory used by the whole JVM process
- The Java heap is only one of the items using memory in the process
- It is (generally) more performant for the JVM to hold (at least some of) the heap it frees after a GC because we're almost certainly going to use this within the next few seconds
- The Java heap in this case is oscillating within the normal bounds, and the default memory configuration in this case allows Java to hold all the excess heap after a GC