I'm currently investigating a compressed class space issue. I know what the issue is, but while investigating, I noticed that jstat -gc ...
and jcmd ... GC.heap_info
give different numbers of metaspace and compressed class space capacity and usage:
▶ jcmd 32152 GC.heap_info
32152:
PSYoungGen total 153600K, used 129316K [0x00000000eab00000, 0x00000000f5b00000, 0x0000000100000000)
eden space 137728K, 91% used [0x00000000eab00000,0x00000000f26abf48,0x00000000f3180000)
from space 15872K, 16% used [0x00000000f4100000,0x00000000f439d428,0x00000000f5080000)
to space 15872K, 0% used [0x00000000f3180000,0x00000000f3180000,0x00000000f4100000)
ParOldGen total 290816K, used 21446K [0x00000000c0000000, 0x00000000d1c00000, 0x00000000eab00000)
object space 290816K, 7% used [0x00000000c0000000,0x00000000c14f1ac0,0x00000000d1c00000)
Metaspace used 59690K, capacity 64980K, committed 65192K, reserved 1103872K
class space used 9289K, capacity 10116K, committed 10152K, reserved 1048576K
▶ jstat -gc 32152
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
15872.0 15872.0 2677.0 0.0 137728.0 126711.2 290816.0 21446.7 63400.0 58060.7 9896.0 9067.2 8 0.047 3 0.118 0.164
The numbers for heap capacities seem to match in general (both survivor, eden, and old gen all capacities all agree). The heap usage numbers don't match exactly, but I wouldn't expect them to; jstat
was collected about a second after jcm
here. But the metaspace numbers are all off, with the jstat
numbers in general being slightly lower than the jcmd
numbers. I reran both commands to confirm that no class loading had occurred between calls, and, indeed, both commands gave the same output for metaspace numbers as before.
What's going on here? Are they measuring these numbers slightly differently? Which is more accurate?
Runtime info:
JVM: Java HotSpot(TM) 64-Bit Server VM (25.202-b08, mixed mode)
Java: version 1.8.0_202, vendor Oracle Corporation
-Xmx1024m
-XX:+UseParallelGC
Good catch! The numbers are indeed different: jstat values can slightly fall behind, since they are updated only after GC, while jcmd values are always current.
So, jcmd GC.heap_info
should be more accurate.
Also note that MC
in jstat output corresponds to the metaspace committed size, not the capacity.