驽马十驾 驽马十驾

驽马十驾,功在不舍

目录
通过 2 种方式获取到 JVM中的Metaspace
/  

通过 2 种方式获取到 JVM中的Metaspace

开篇

之前文章有提到 jstat的用处,当时的情形服务器发生了Metaspace下的OOM的情况,该情形下,dump 堆内存是没有用处的,因为Metaspace不在Heap下,而是在Non-Heap中。

通常而言:

Non-Heap=Metaspace + JIT【不是所有的对象都是堆上】+ Native Method Allcatoted Heap + Code Cache + Threads...

MetaSpace=Non-Class space + Class Space

  • Class Space 主要是类的描述:Kclass/vtable/itable
  • `Non-Class 主要是常量池、方法签名、返回值、注解数据等

获取

方法 1:jstat

这个是在 JDK8以下可以使用的

jstat gc <PID>

打印的数据如下所示

S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
 0.0   12288.0  0.0   12288.0 814080.0 477184.0 1270784.0   373457.9  258176.0 229699.4 31360.0 26547.5    821   15.867   0      0.000   15.867

其中Metaspace相关的数据是:

  • MC: Metaspace总的容量
  • MU: Metaspace 使用的量
  • CCSC:Class Space总的容量
  • CCSU:Class Space 当前使用量

上面有提到MetaSpace=Non-Class space + Class Space,所以假如要获取到Non-Class的空间数据,那么需要使用:MU-CCSU

同时需要了解到,系统稳定下来后, Metaspace 中 Class Space 通常不会变化的。

方法 2:jcmd pid VM.metaspace

该方法在 JDK8 是不支持的,在JDK11中可以支持,使用起来非常方便,如下指令获取元数据空间。

jcmd <PID> VM.metaspace

该方法的输出更直观:

Total Usage - 4996 loaders, 27250 classes:
  Non-Class: 11005 chunks,   136.93 MB capacity,   133.32 MB ( 97%) used,     2.93 MB (  2%) free,     8.14 KB ( <1%) waste,   687.81 KB ( <1%) overhead, deallocated: 3736 blocks with 1.02 MB
      Class: 5466 chunks,     19.54 MB capacity,    17.23 MB ( 88%) used,     1.97 MB ( 10%) free,   128 bytes ( <1%) waste,   341.62 KB (  2%) overhead, deallocated: 432 blocks with 119.36 KB
       Both: 16471 chunks,   156.47 MB capacity,   150.56 MB ( 96%) used,     4.90 MB (  3%) free,     8.27 KB ( <1%) waste,     1.01 MB ( <1%) overhead, deallocated: 4168 blocks with 1.13 MB

包括了Non-ClassClass等更多信息

结语

今天就写这么多。。。

骐骥一跃,不能十步。驽马十驾,功在不舍。