Sidebar
0 votes
43 views
by ben-s-7515 (13.6k points)
I have set my -Xmx java option to 28G, but when I monitor the memory usage from the OS task view, it tells me that the JVM is actually using 32G of memory.

Why are these values not matching?

1 Answer

0 votes

That is a classic and frequent observation when monitoring a Java Virtual Machine (JVM). The reason the Operating System (OS) reports more memory usage than the sum of the JVM's memory pools is that the OS reports the entire process footprint, while the JVM's memory pool beans only report the areas managed by the Garbage Collector (GC) and JIT compiler.

The difference lies in the memory allocated for JVM Native Memory which is not tracked by the standard MemoryPoolMXBeans (like Eden, Old Gen, Metaspace, or CodeHeap).

The "missing" memory is primarily consumed by internal, non-heap allocations the JVM requires to function.


1. Thread Stacks

Every time a Java thread is created, the JVM allocates a fixed block of memory in native space for that thread's stack. This stack is used to hold local variables, method call frames, and return addresses.

  • Impact: This is usually the largest source of discrepancy. On 64-bit systems, the default stack size is often 1MB. An application with 200 threads would immediately reserve 200 * 1 {MB} = 200 {MB} of native memory that is not reported in any standard memory pool.
  • Programmatic Reporting: There is no standard JMX bean to report the sum of thread stack usage.

2. Garbage Collector (GC) Internal Data Structures

The G1 GC (and other modern collectors) requires significant internal data structures to manage the heap, track references, and enable concurrent collection. This memory is allocated in native space.

  • G1 Overhead: For the G1 GC, this includes structures like Remembered Sets (RSet) and Card Tables. These structures track cross-region references and can consume a notable amount of memory, especially with a large heap or a high number of regions.


3. Other JVM Internal Data

The JVM itself is a complex native C++ application that needs memory for:

  • Symbol Table: Storing constant pool entries, field names, and method signatures.

  • String Table: Storing interned strings (which are references to heap objects, but the table itself is native).

  • JNI (Java Native Interface) code and temporary buffers.

  • Loaded Libraries: The memory occupied by the JVM executables and loaded native libraries (like DLLs or SOs).

by ben-s-7515 (13.6k points)
...