javagarbage-collectionjvmmetaspace

Does JVM metaspace always trigger GC when resizing


For JVM after Java 8

  1. When the size of metaspace > -XX:metaspaceSize, it will trigger a gc.
  2. No matter how you configure -XX:metaspaceSize and -XX:maxMetaspaceSize, the initial size of metaspace is usually a fixed value (20.8M) on a 64-bit server.
  3. The JVM will resize metaspace automatically when it reaches close to the current capacity.
  4. Then, if -XX:metaspaceSize is 20G for example, the current size of the metaspace is 18M and a large number of new objects (about 100M) must be allocated, the JVM must resize the metaspace for these new objects, will JVM triggers a full GC before resizing?

Solution

  • First of all, "the size of the metaspace" is ambiguous, and thus meaningless without the context. There are at least five metrics: reserved, committed, capacity and used memory as described in this answer, and the high-water mark, also known as capacity_until_gc.

    Metaspace layout

    Metaspace is not just one contiguous region of memory, so it does not resize in the common sense. Instead, when allocation happens, one or more of the above metrics changes.

    1. On the fastest path a block of metadata is allocated from the current chunk. used memory increases in this case, and that's it.
    2. If there is not enough room in the current chunk, JVM searches for a possibly free existing chunk. If it succeeds in reusing chunks, capacity increases. No GC happens until this point.
    3. If there are no free chunks, JVM tries to commit more memory, unless the new committed size would exceed capacity_until_gc.
    4. If capacity_until_gc threshold is reached, JVM triggers a GC cycle.
    5. If GC does not free enough memory, the high-water mark is increased so that another Virtual Space will be allocated.

    After GC, the high-water mark value is adjusted basing on the following JVM flags:

    TL;DR It's not that simple. JVM can definitely commit more Metaspace memory without triggering GC. However, when HWM is reached, GC is triggered and HWM is recomputed according to the ergonomics policy.