温馨提示:本篇内容基于Java 8编写,使用不同版本可能存在部分输出内容不符。
jstat是一个用于监视虚拟机各种运行状态信息的命令行工具。可以查看本地或者远程虚拟机中的类装载、内存、垃圾收集、JIT编译等运行数据。在 日常工作中,可以帮我我们去观察JVM内存的分配情况、使用率、GC的次数以及耗时,为今后的性能调优提供基础分析数据。
语法:jstat [ generalOption | outputOptions vmid [ interval [s | ms] [ count ]]
例如:
jstat -help|-options
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
语法说明
generalOption:
常规选项,例如-help、-options选项,如果指定一个常规选项,则无法指定任何其他选项或参数。也就是说jstat后面如果使用了-help 或者-options就不能再追加使用其他选项
例如:
- 查看帮助信息:jstat -help
[root@localhost ~]$ jstat -help
Usage: jstat -help|-options
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
Definitions:
<option> An option reported by the -options option
<vmid> Virtual Machine Identifier. A vmid takes the following form:
<lvmid>[@<hostname>[:<port>]]
Where <lvmid> is the local vm identifier for the target
Java virtual machine, typically a process id; <hostname> is
the name of the host running the target Java virtual machine;
and <port> is the port number for the rmiregistry on the
target host. See the jvmstat documentation for a more complete
description of the Virtual Machine Identifier.
<lines> Number of samples between header lines.
<interval> Sampling interval. The following forms are allowed:
<n>["ms"|"s"]
Where <n> is an integer and the suffix specifies the units as
milliseconds("ms") or seconds("s"). The default units are "ms".
<count> Number of samples to take before terminating.
-J<flag> Pass <flag> directly to the runtime system.
以上的帮助信息,其实已经包含了很多介绍,大家可以自行学习一下。
- 查看选项信息:jstat -options
[root@localhost ~]$ jstat -options
-class
-compiler
-gc
-gccapacity
-gccause
-gcmetacapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcutil
-printcompilation
使用 -options选项,可以列出jstat支持的所有outputOptions(输出选项)我们平时使用最多的,就是输出选项中的这些命令。
outputOptions:
输出选项,如果未指定常规选项,则可以指定输出选项,由单个的statOption,加上任何的另一个输出选项(-h或-t)
例如:
[root@localhost ~]$ jstat -gc -t 22979
Timestamp S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
2744532.5 52416.0 52416.0 0.0 0.0 419392.0 272913.5 64.0 64.0 786432.0 52243.1 619 263.428 714286 251783.764 252047.192
可以看到,在命令中使用了-t参数,它在第一列打印了时间戳。
vmid:
如果是本机的虚拟机进程,它就是进程号,如果是远程虚拟机格式为:
[protocol:][//]lvmid[@hostname[:port]/servername]
这种方式并不推荐常用,所以仅需了解即可。后续会更新使用方式。
interval和count:
interval代表查询间隔,count代表查询次数,若省略这两个参数,表示只查询一次。
例如:
[root@localhost ~]$ jstat -gcnew 22979 1000 5
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
52416.0 52416.0 0.0 0.0 1 6 26208.0 419392.0 275960.4 619 263.428
52416.0 52416.0 0.0 0.0 1 6 26208.0 419392.0 275960.4 619 263.428
52416.0 52416.0 0.0 0.0 1 6 26208.0 419392.0 275960.4 619 263.428
52416.0 52416.0 0.0 0.0 1 6 26208.0 419392.0 275960.5 619 263.428
52416.0 52416.0 0.0 0.0 1 6 26208.0 419392.0 275960.5 619 263.428
这个命令表示每隔一秒(1000毫秒)打印一次新生代的GC情况,一共打印5次
jstat主要选项
使用jstat -options可以列出所有的选项:
-class:显示类加载的统计信息
-compiler:显示有关Java HotSpot VM实时编译器(JIT)行为的统计信息
-gc:显示各个内存区域容量和GC信息
-gccapacity:显示堆的容量的详细信息
-gccause:显示有关垃圾收集统计信息(和-gcutil功能一样),但是会输出上一次GC产生的原因
-gcmetacapacity:显示有关元空间大小的统计信息
-gcnew:显示新生代GC信息
-gcnewcapacity:显示新生代的容量信息和GC信息
-gcold:显示老年代和元空间GC信息
-gcoldcapacity:和-gcold功能基本一致,但是会输出相应空间大小的统计信息
-gcutil:显示有关垃圾回收统计信息,展示的是百分比的数据
-printcompilation:显示Java HotSpot VM编译统计信息
-class 示例:
[root@localhost ~]$ jstat -class 30934
Loaded Bytes Unloaded Bytes Time
13383 24329.7 0 0.0 9.10
Loaded:加载的类的数量
Bytes:加载的字节数
Unloaded:卸载的类的数量
Bytes:卸载的字节数
Time:执行类加载和卸载操作所花费的时间
这个示例展示了进程号为30934的程序它的类装载情况,根据结果可以看出,它一共加载了13383个类(Loaded)、一共24329.7kb(Bytes)、卸载了0个类(Unloaded)、卸载类的总大小为0kb(Bytes)以及执行类的加载和卸载一共花费了9.1秒(Time)
-compiler 示例:
[root@localhost ~]$ jstat -compiler 30934
Compiled Failed Invalid Time FailedType FailedMethod
18224 2 0 120.79 1 com/mysql/jdbc/AbandonedConnectionCleanupThread run
列名含义:
Compiled:执行的编译任务数
Failed:编译任务失败的数量
Invalid:已失效的编译任务数
Time:执行编译任务所花费的时间
FailedType:编译上次失败的编译的类型
FailedMethod:上次失败编译的类名和方法
-gc 示例:
进程信息:
[root@localhost ~]$ jps -v
30934 jar -Xms512M -Xmx512M
通过jps工具,我们可以看到进程30934启动时JVM的参数,设置JVM最大可用内存为512M,初始内存为512M。有了这个前置条件,我们来分析这个进程GC的相关信息。
[root@localhost ~]$ jstat -gc 30934
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
1024.0 1024.0 544.0 0.0 172544.0 88232.1 349696.0 81249.4 76632.0 74629.2 9088.0 8627.8 452 3.323 3 0.521 3.844
列名含义:
S0C:当前survivor space 0总容量(kB)
S1C:当前survivor space 1总容量(kB)
S0U:survivor space 0已使用容量(kB)
S1U:survivor space 1已使用容量(kB)
EC:当前eden space总容量(kB)
EU:eden space已使用容量(kB)
OC:当前old space总容量(kB)
OU:old space的已使用容量(kB)
MC:Metaspace 总容量(kB)
MU:Metacspace已使用容量(kB)
CCSC:压缩类空间总容量(kB)
CCSU:已使用的压缩类空间容量(kB)
YGC:Young generation GC次数
YGCT:Young generation GC总耗时
FGC:Full GC次数
FGCT:Full GC总耗时
GCT:GC总耗时
在-gc之后显示的数据中,包含各种简写,上面的列表也列出了他们各自的含义,现在来验证一下总容量,总容量=survivor + Eden + old space
在输出结果中得知:
S0 = 1024
S1 = 1024
Eden = 172544
old space = 349696
totalCapacity = (1024 + 1024 + 172544 + 349696)/ 1024
结果:
512M
由计算结果可以得知,上述概念是正确的。从输出结果来看,我们可以了解到这个JVM进程的一些内存使用状况,其次,可以看到不同区域的垃圾回收次数以及垃圾回收的总耗时。
-gccapacity 示例:
[root@localhost ~]$ jstat -gccapacity 30934
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
174592.0 174592.0 174592.0 1024.0 1024.0 172544.0 349696.0 349696.0 349696.0 349696.0 0.0 1116160.0 76632.0 0.0 1048576.0 9088.0 453 3
-gccapacity主要用于体现java堆各个区域使用到的最大、最小空间,单位kb
列名含义:
NGCMN:new generation使用到的最小容量
NGCMX:new generation使用到的最大容量
NGC:new generation当前的容量
S0C:survivor0当前的容量
S1C:survivor1当前的容量
EC:Eden当前的容量
OGCMN:old generation使用到的最小容量
OGCMX:old generation使用到的最大容量
OGC:old generation当前的容量
OC:old space当前容量
MCMN:metaspace 使用到的最小容量
MCMX:metaspace 使用到的最大容量
MC:metaspace 空间容量
CCSMN:压缩类空间最小容量
CCSMX:压缩类空间最大容量
CCSC:压缩类空间容量
YGC:Young GC次数
FGC:Full GC次数
-gccause 示例:
[root@localhost ~]$ jstat -gccause 30934 2000
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
0.00 53.12 80.17 23.23 97.39 94.94 453 3.331 3 0.521 3.852 Allocation Failure No GC
列名含义:
LGCC:上次发生GC的原因
GCC:本次发生GC的原因
它和-gcutil显示内容一样,但是多了上次GC发生的原因和本次GC发生的原因,由结果可以看出,上次是因为无法分配空间,来了一次GC。
-gcutil 示例:
[root@localhost ~]$ jstat -gcutil 30934
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 53.12 94.21 23.23 97.39 94.94 453 3.331 3 0.521 3.852
列名含义:
S0:survivor0空间使用率
S1:survivor1空间使用率
E:Eden空间使用率
O:old generation空间使用率
M:metaspace空间使用率
CCS:压缩类空间使用率
YGC:Young generation GC次数
YGCT:Young generaton GC 耗时
FGC:Full GC 次数
FGCT:Full GC 耗时
GCT:所有GC总耗时
这里所说的使用率,是指JVM分配给S0 、S1、Eden等空间的内存使用率,是相对于S0、S1、Eden等它自身容量来计算的,我们可以结合前面学习到的-gc来查询他们各自的总容量,和使用量,然后来验证一下它数据的准确性。
使用-gc查看总容量和使用量:
[root@localhost ~]$ jstat -gc 30934
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
1024.0 1024.0 0.0 544.0 172544.0 161813.9 349696.0 81249.4 76632.0 74629.2 9088.0 8627.8 453 3.331 3 0.521 3.852
现以Survivor空间使用量来验证一下,由-gc得知Survivor0总容量为1024,已使用0,所以在-gcutil之后显示的使用率为0,Survivor1的总容量为1024,已使用544,那么使用率是544/1024 = 53.12%符合-gcutil所统计的数据。
-gcmetacapacity 示例
[root@localhost ~]$ jstat -gcmetacapacity 30934 2000 5
MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT
0.0 1116160.0 76632.0 0.0 1048576.0 9088.0 462 3 0.521 3.913
列名含义:
MCMN: Metaspace 最小容量
MCMX: Metaspace 最大容量
MC: Metaspace 容量
CCSMN: 压缩类空间最小容量.
CCSMX: 压缩类空间最大容量
YGC: Young generation GC 次数
FGC: Full GC 次数
FGCT: Full GC 耗时
GCT: GC总耗时
-gcnew 示例:
[root@localhost ~]$ jstat -gcnew 30934
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
1024.0 1024.0 512.0 0.0 15 15 1024.0 172544.0 145247.1 462 3.392
列名含义:
S0C: Survivor space 0 总容量
S1C: Survivor space 1 总容量
S0U: Survivor space 0 已使用容量
S1U: Survivor space 1 已使用容量
TT: 晋升阈值(实际上是指对象的年龄,最大15,表示它会被放入Old generation了)
MTT: 最大晋升阈值(最大15)
DSS: 期望Survivor大小
EC: Eden space 总容量
EU: Eden space 已使用容量
YGC: Young generation GC 次数
YGCT: Young generation GC 耗时
-gcnewcapacity 示例:
[root@localhost ~]$ jstat -gcnewcapacity 30934
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
174592.0 174592.0 174592.0 57856.0 1024.0 57856.0 1024.0 173568.0 172544.0 462 3
列名含义:
NGCMN: New generation 最小容量
NGCMX: New generation 最大容量
NGC: New generation 当前容量
S0CMX: Survivor space 0 最大容量
S0C: Survivor space 0 当前容量
S1CMX: Survivor space 1 最大容量
S1C: Survivor space 1 当前容量
ECMX: Eden space 最大容量
EC: Eden space 当前容量
YGC: Young generation GC 次数
FGC: Full GC 次数
提示:
在Java8中New generation = Survivor0 + Survivor1 + Eden
-gcold 示例:
[root@localhost ~]$ jstat -gcold 30934
MC MU CCSC CCSU OC OU YGC FGC FGCT GCT
76632.0 74629.6 9088.0 8627.8 349696.0 81305.4 463 3 0.521 3.920
列名含义:
MC: Metaspace 容量
MU: Metaspace 已使用容量
CCSC: Compressed class space 容量
CCSU: Compressed class space 已使用容量
OC: Old space 容量
OU: Old space 已使用容量
YGC: Young generation GC 次数
FGC: Full GC 次数
FGCT: Full GC 耗时
GCT: 所有GC总耗时
-gcoldcapacity 示例:
[root@localhost ~]$ jstat -gcoldcapacity 30934
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
349696.0 349696.0 349696.0 349696.0 463 3 0.521 3.920
列名含义:
OGCMN: Old generation 最小容量
OGCMX: Old generation 最大容量
OGC: Old generation 当前容量
OC: Old space 当前容量
YGC: Young generation GC 次数
FGC: Full GC 次数
FGCT: Full GC 耗时
GCT: 所有GC总耗时
-printcompilation 示例:
[root@localhost ~]$ jstat -printcompilation 30934
Compiled Size Type Method
18226 48 1 sun/nio/ch/SocketOptionRegistry$RegistryKey equals
列名含义:
Compiled: 最近编译任务执行的次数
Size: 最近编译的字节数
Type: 最近编译的类型
Method: 最近编译的类名,方法名