javajvmmetaspacejstatjcmd

jstat and jcmd giving different answers for metaspace memory


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

Solution

  • 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.