javagarbage-collectionmetaspace

Metaspace allocated more then MaxMetaspaceSize


In Java 8, I run GC log on my service and via GCeasy I saw that 1GB is allocated to the metaspace, while the peak was around 40m, so why 1 GB was allocated?

I play with the flags and added "-XX:MaxMetaspaceSize=10M".

Then I got java.lang.OutOfMemoryError: Metaspace, as expected, but still on the GC log I saw that 1 GB was allocated. Is there a bug in the logs? or I'm missing something.

I run grep Metaspace on the GC log file and got the below output:

CommandLine flags: -XX:CompressedClassSpaceSize=2097152 -XX:+DisableExplicitGC -XX:GCLogFileSize=104857600 -XX:InitialHeapSize=536870912 -XX:MaxHeapSize=536870912 -XX:MaxMetaspaceSize=10485760 -XX:MetaspaceSize=10485760 -XX:NumberOfGCLogFiles=10 -XX:+PrintGC -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:ReservedCodeCacheSize=134217728 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseGCLogFileRotation -XX:+UseParallelGC

2020-05-19T16:38:18.359+0000: 0.837: [Full GC (Metadata GC Threshold) [PSYoungGen: 7298K->0K(153088K)] [ParOldGen: 8K->6944K(349696K)] 7306K->6944K(502784K), [Metaspace: 9975K->9975K(1058816K)], 0.0249384 secs] [Times: user=0.08 sys=0.01, real=0.02 secs]

2020-05-19T16:38:18.386+0000: 0.864: [Full GC (Metadata GC Threshold) [PSYoungGen: 0K->0K(153088K)] [ParOldGen: 6944K->6944K(349696K)] 6944K->6944K(502784K), [Metaspace: 9975K->9975K(1058816K)], 0.0129850 secs] [Times: user=0.04 sys=0.00, real=0.01 secs]

2020-05-19T16:38:18.400+0000: 0.879: [Full GC (Last ditch collection) [PSYoungGen: 0K->0K(153088K)] [ParOldGen: 6944K->6816K(349696K)] 6944K->6816K(502784K), [Metaspace: 9975K->9965K(1058816K)], 0.0252318 secs] [Times: user=0.07 sys=0.00, real=0.03 secs]


Solution

  • The answer is basically here, though not trivial to understand.

    The MaxMetaspaceSize limits the committed memory, while your GC logs actually print the reserved memory. So reserved: 1058816K, committed: 9975K, according to your log. Reserved memory does not have to be backed by swap or actual RAM, at all, so usually it is very big.

    That is why you see those big numbers in the GC log.