四、jdk工具之jstat命令2(Java Virtual Machine Statistics Monitoring Tool)详解
目录
一、jdk工具之jps(JVM Process Status Tools)命令使用
二、jdk命令之javah命令(C Header and Stub File Generator)
三、jdk工具之jstack(Java Stack Trace)
四、jdk工具之jstat命令(Java Virtual Machine Statistics Monitoring Tool)
四、jdk工具之jstat命令2(Java Virtual Machine Statistics Monitoring Tool)详解
五、jdk工具之jmap(java memory map)、 mat之四--结合mat对内存泄露的分析
六、jdk工具之jinfo命令(Java Configuration Info)
七、jdk工具之jconsole命令(Java Monitoring and Management Console)
八、jdk工具之JvisualVM、JvisualVM之二--Java程序性能分析工具Java VisualVM
九、jdk工具之jhat命令(Java Heap Analyse Tool)
十、jdk工具之Jdb命令(The Java Debugger)
十一、jdk命令之Jstatd命令(Java Statistics Monitoring Daemon)
时间是:毫秒
单位是:KB
jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:
jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]
注意:使用的jdk版本是jdk8.
GC频率监控
- jstat -class 类加载统计
- jstat -compiler 编译统计
- jstat -GC 垃圾回收统计
- jstat -gccapacity 堆内存统计
- jstat -gccnew 年轻代垃圾回收统计
- jstat -gccold 老年代垃圾回收统计
- jstat -gcnewcapacity 年轻代内存统计
- jstat -gcoldcapacity 老年代内存统计
- jstat -gcmetacapacity 元空间内存统计
- jstat -gcutil gc整体统计
- jstat -gccause gc原因
类加载统计:
/ $ jstat -class 9 Loaded Bytes Unloaded Bytes Time 15046 27276.6 0 0.0 17.62
Loaded:加载class的数量
Bytes:所占用空间大小
Unloaded:未加载数量
Bytes:未加载占用空间
Time:时间
编译统计
/ $ jstat -compiler 9 Compiled Failed Invalid Time FailedType FailedMethod 30239 1 0 206.89 1 sun/misc/URLClassPath getLoader / $
Compiled:编译数量。
Failed:失败数量
Invalid:不可用数量
Time:时间
FailedType:失败类型
FailedMethod:失败的方法
垃圾回收统计
/ $ jstat -gc 9 3000 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 12800.0 12800.0 0.0 11851.2 760832.0 314974.7 1572864.0 534338.9 89108.0 85979.5 10556.0 9943.9 4327 76.753 3 0.513 77.266 12800.0 12800.0 0.0 11851.2 760832.0 317333.1 1572864.0 534338.9 89108.0 85979.5 10556.0 9943.9 4327 76.753 3 0.513 77.266 12800.0 12800.0 0.0 11851.2 760832.0 319062.1 1572864.0 534338.9 89108.0 85979.5 10556.0 9943.9 4327 76.753 3 0.513 77.266 12800.0 12800.0 0.0 11851.2 760832.0 321439.5 1572864.0 534338.9 89108.0 85979.5 10556.0 9943.9 4327 76.753 3 0.513 77.266
S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:元数据区大小
MU:元数据区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
堆内存统计
^C/ $ jstat -gccapacity 9 NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC 786432.0 786432.0 786432.0 12800.0 12800.0 760832.0 1572864.0 1572864.0 1572864.0 1572864.0 0.0 1128448.0 89108.0 0.0 1048576.0 10556.0 4327 3 / $
NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
EC:伊甸园区的大小
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:当前老年代大小
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代gc次数
FGC:老年代GC次数
新生代垃圾回收统计
/ $ jstat -gcnew 9 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT 12800.0 12800.0 0.0 11851.2 15 15 12800.0 760832.0 519602.9 4327 76.753 / $
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
TT:对象在新生代存活的次数
MTT:对象在新生代存活的最大次数
DSS:期望的幸存区大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
新生代内存统计
/ $ jstat -gcnewcapacity 9 NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC 786432.0 786432.0 786432.0 262144.0 12800.0 262144.0 12800.0 785408.0 760832.0 4327 3 / $
NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0CMX:最大幸存1区大小
S0C:当前幸存1区大小
S1CMX:最大幸存2区大小
S1C:当前幸存2区大小
ECMX:最大伊甸园区大小
EC:当前伊甸园区大小
YGC:年轻代垃圾回收次数
FGC:老年代回收次数
老年代垃圾回收统计
/ $ jstat -gcold 9 MC MU CCSC CCSU OC OU YGC FGC FGCT GCT 89108.0 85979.5 10556.0 9943.9 1572864.0 534338.9 4327 3 0.513 77.266 / $
MC:元数据区大小
MU:元数据区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
OC:老年代大小
OU:老年代使用大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
---------------------------------------------------------------------------------------------------------------------
jstat里的metaspace字段
我们看GC是否异常,除了通过GC日志来做分析之外,我们还可以通过jstat这样的工具展示的数据来分析,前面我公众号里有篇文章介绍了jstat这块的实现,有兴趣的可以到我的公众号你假笨
里去翻阅下jstat的这篇文章。
我们通过jstat可以看到metaspace相关的这么一些指标,分别是M
,CCS
,MC
,MU
,CCSC
,CCSU
,MCMN
,MCMX
,CCSMN
,CCSMX
它们的定义如下:
column { header "^M^" /* Metaspace - Percent Used */ data (1-((sun.gc.metaspace.capacity - sun.gc.metaspace.used)/sun.gc.metaspace.capacity)) * 100 align right width 6 scale raw format "0.00" } column { header "^CCS^" /* Compressed Class Space - Percent Used */ data (1-((sun.gc.compressedclassspace.capacity - sun.gc.compressedclassspace.used)/sun.gc.compressedclassspace.capacity)) * 100 align right width 6 scale raw format "0.00" } column { header "^MC^" /* Metaspace Capacity - Current */ data sun.gc.metaspace.capacity align center width 6 scale K format "0.0" } column { header "^MU^" /* Metaspae Used */ data sun.gc.metaspace.used align center width 6 scale K format "0.0" } column { header "^CCSC^" /* Compressed Class Space Capacity - Current */ data sun.gc.compressedclassspace.capacity width 8 align right scale K format "0.0" } column { header "^CCSU^" /* Compressed Class Space Used */ data sun.gc.compressedclassspace.used width 8 align right scale K format "0.0" } column { header "^MCMN^" /* Metaspace Capacity - Minimum */ data sun.gc.metaspace.minCapacity scale K align right width 8 format "0.0" } column { header "^MCMX^" /* Metaspace Capacity - Maximum */ data sun.gc.metaspace.maxCapacity scale K align right width 8 format "0.0" } column { header "^CCSMN^" /* Compressed Class Space Capacity - Minimum */ data sun.gc.compressedclassspace.minCapacity scale K align right width 8 format "0.0" } column { header "^CCSMX^" /* Compressed Class Space Capacity - Maximum */ data sun.gc.compressedclassspace.maxCapacity scale K align right width 8 format "0.0" }
我这里对这些字段分类介绍下
MC & MU & CCSC & CCSU
-
MC表示Klass Metaspace以及NoKlass Metaspace两者总共committed的内存大小,单位是KB,虽然从上面的定义里我们看到了是capacity,但是实质上计算的时候并不是capacity,而是committed,这个是要注意的
-
MU这个无可厚非,说的就是Klass Metaspace以及NoKlass Metaspace两者已经使用了的内存大小
-
CCSC表示的是Klass Metaspace的已经被commit的内存大小,单位也是KB
-
CCSU表示Klass Metaspace的已经被使用的内存大小
M & CCS
-
M表示的是Klass Metaspace以及NoKlass Metaspace两者总共的使用率,其实可以根据上面的四个指标算出来,即(CCSU+MU)/(CCSC+MC)
-
CCS表示的是Klass Metaspace的使用率,也就是CCSU/CCSC算出来的
PS:所以我们有时候看到M的值达到了90%以上,其实这个并不一定说明metaspace用了很多了,因为内存是慢慢commit的,所以我们的分母是慢慢变大的,不过当我们committed到一定量的时候就不会再增长了
MCMN & MCMX & CCSMN & CCSMX
-
MCMN和CCSMN这两个值大家可以忽略,一直都是0
-
MCMX表示Klass Metaspace以及NoKlass Metaspace两者总共的reserved的内存大小,比如默认情况下Klass Metaspace是通过CompressedClassSpaceSize这个参数来reserved 1G的内存,NoKlass Metaspace默认reserved的内存大小是2* InitialBootClassLoaderMetaspaceSize
-
CCSMX表示Klass Metaspace reserved的内存大小
综上所述,其实看metaspace最主要的还是看MC
,MU
,CCSC
,CCSU
这几个具体的大小来判断metaspace到底用了多少更靠谱
---------------------------------------------------------------------------------------------------------------------
老年代内存统计
/ $ jstat -gcoldcapacity 9 OGCMN OGCMX OGC OC YGC FGC FGCT GCT 1572864.0 1572864.0 1572864.0 1572864.0 4327 3 0.513 77.266 / $
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:老年代大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
元数据空间统计
/ $ jstat -gcmetacapacity 9 MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT 0.0 1128448.0 89108.0 0.0 1048576.0 10556.0 4327 3 0.513 77.266 / $
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
总结垃圾回收统计
/ $ jstat -gcutil 9 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 40.55 0.00 17.43 33.97 96.49 94.20 4328 76.766 3 0.513 77.279 / $
S0:幸存1区当前使用比例
S1:幸存2区当前使用比例
E:伊甸园区使用比例
O:老年代使用比例
M:元数据区使用比例
CCS:压缩使用比例
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
说明:
FGC数量大时,有内存泄漏的问题;
FGCT执行时间长,会导致系统的响应时间较长,若JVM的内存设置较大,那么执行一次FGC的时间可能会更长。
FGC对服务器性能影响:发生FGC时,服务响应时间会增加,网络请求和吞吐量会下降。
所以java内存泄漏对系统性能的影响是不可忽视的。
JVM编译方法统计
/ $ jstat -printcompilation 9 Compiled Size Type Method 30243 154 1 com/fasterxml/jackson/databind/util/ClassUtil findSuperTypes / $
Compiled:最近编译方法的数量
Size:最近编译方法的字节码数量
Type:最近编译方法的编译类型。
Method:方法名标识。
GCT=YGCT+FGCT
总的垃圾回收时间=年轻代垃圾回收时间+老年代垃圾回收时间
上面的红色框中发生一次FGC,可以验证。
jstat -gccause gc原因
/ $ jstat -gccause 11 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC 57.50 0.00 57.44 76.65 89.75 84.73 4132 49.547 1 0.516 50.064 Allocation Failure No GC / $