java性能分析--GC分析利器【jstat】

927 阅读7分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

本篇文章继续学习java性能优化工具jstat,通常我们是使用这个命令去查看jvm的gc情况,下面来具体学习下它的用法。想要好更好的学习本篇内容,请先学习了解JVM相关知识,便于理解。

jstat简介

jstat是jdk自带的工具,可以实时的对应用性能和资源进行监控,提供类装载信息和GC活动信息。

下面通过帮助文档看下使用方式:

[root@hecs-402944 ~]# 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 -help 或者 jstat -options

    • 帮助文档的就不详细解释了
    • jstat -options 为我们提供了一系列的参数,如下所示:
        [root@hecs-402944 ~]# jstat -options
        -class
        -compiler
        -gc
        -gccapacity
        -gccause
        -gcmetacapacity
        -gcnew
        -gcnewcapacity
        -gcold
        -gcoldcapacity
        -gcutil
        -printcompilation
      
  • 使用 -options提供的参数进行命令操作

jstat使用介绍

本小节主要讲解适用方式,不讲解帮助当中的主要参数了,比较晦涩和复杂,主要介绍常规使用方式。下面的内容需要大家对jvm有较深的了解,不了解的可以参考下面的文章简单学习下: # jdk1.8 内存模型

在前面我们看到jstat -options为我们提供了很多的参数,下面我们来看下它们的作用。

首先获取进程的pid:

[root@hecs-402944 ~]# jps
21203 jar
22476 Jps

使用格式:jstat -option -timeLength -times

参数含义:

  • -option jstat -options提供的参数
  • -timeLength 时间间隔,单位是毫秒
  • -times 打印次数

-class

动态打印被加载的类的个数和大小:

[root@hecs-402944 ~]# jstat -class 21203 1000 3
Loaded  Bytes  Unloaded  Bytes     Time   
 10675 20275.1      157   234.7       8.24
 10675 20275.1      157   234.7       8.24
 10675 20275.1      157   234.7       8.24

如上所示,表示加载了10675个类,大小是20275.1Byte,未加载157,大小是234.7Byte,用时8.24s。

-compiler

动态打印编译数量:

[root@hecs-402944 ~]# jstat -compiler 21203 1000 3
Compiled Failed Invalid   Time   FailedType FailedMethod
    9267      0       0    17.34          0             
    9267      0       0    17.34          0             
    9267      0       0    17.34          0 

如上表示编译9267个文件,失败0,错误0,耗时17.34s,失败类型0,失败方法无。

-gc

动态打印GC的次数:

[root@hecs-402944 ~]# jstat -gc 21203 1000 3
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
18944.0 18944.0  0.0   10129.0 311296.0 53676.4   699392.0   17807.7   64424.0 60536.1 7856.0 7158.9     11    0.119   6      0.516    0.635
18944.0 18944.0  0.0   10129.0 311296.0 53676.4   699392.0   17807.7   64424.0 60536.1 7856.0 7158.9     11    0.119   6      0.516    0.635
18944.0 18944.0  0.0   10129.0 311296.0 53676.4   699392.0   17807.7   64424.0 60536.1 7856.0 7158.9     11    0.119   6      0.516    0.635

我们知道,jvm当中,堆内存模型被分为伊甸园区,年轻代,老年代,方法区,其中年轻代又分为幸存者0区幸存者1区,所以上面打印的含义如下:

  • S0C 幸存者0区大小
  • S1C 幸存者1区大小
  • S0U 幸存者0区使用
  • S1U 幸存者1区使用
  • EC 伊甸园区大小
  • EU 伊甸园区使用
  • OC 老年代大小
  • OU 老年代使用
  • MC 方法区大小
  • MU 方法区使用
  • CCSC 压缩类空间大小
  • CCSU 压缩类空间使用
  • YGC 年轻代垃圾回收数
  • YGCT 年轻代垃圾回收时间
  • FGC 老年代垃圾回收数 - Full GC次数
  • FGCT 老年代垃圾回收时间
  • GCT 垃圾回收总时间

根据这些含义,我们做一下运算:

  • 两个幸存者区大小 + 伊甸园区大小 + 老年代大小 = 1048576 Byte
  • 1048576B / 1024 = 1024 MB = 1g

最终的结果刚好等于此项目初始分配的堆空间大小1G。

-gccapacity

此参数与前面的 -gc相比,增加了最大、最小容量的显示,其中MN表示最小MX表示最大,所以不再单独列举了:

[root@hecs-402944 ~]# jstat -gccapacity 21203 1000 3
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC 
349184.0 349184.0 349184.0 18944.0 18944.0 311296.0   699392.0   699392.0   699392.0   699392.0      0.0 1105920.0  64424.0      0.0 1048576.0   7856.0     11     6
349184.0 349184.0 349184.0 18944.0 18944.0 311296.0   699392.0   699392.0   699392.0   699392.0      0.0 1105920.0  64424.0      0.0 1048576.0   7856.0     11     6
349184.0 349184.0 349184.0 18944.0 18944.0 311296.0   699392.0   699392.0   699392.0   699392.0      0.0 1105920.0  64424.0      0.0 1048576.0   7856.0     11     6

-gccause

此参数用于输出除内存使用之外,gc的次数和时间,以及gc的原因

[root@hecs-402944 ~]# jstat -gccause 21203 1000 3
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC                 
  0.00  53.47  17.34   2.55  93.97  91.13     11    0.119     6    0.516    0.635 Allocation Failure   No GC               
  0.00  53.47  17.34   2.55  93.97  91.13     11    0.119     6    0.516    0.635 Allocation Failure   No GC               
  0.00  53.47  17.34   2.55  93.97  91.13     11    0.119     6    0.516    0.635 Allocation Failure   No GC 
  • S0 S1 E O M CSS 分别表示幸存者0区,幸存者1区,伊甸园区,老年代,方法区,压缩类空间的使用百分比。
  • YGC 年轻代GC次数
  • YGCT 年轻代GC耗时
  • FGC 老年代GC次数
  • FGCT 老年代GC耗时
  • GCT GC总耗时
  • LGCC 最后一次GC的原因
  • GGC 当前GC的原因

上面的内容除了GC原因都很好理解,失败原因也是字面意思Allocation Failure,内存分配失败了,除此之外还有很多种,同学们可以参考下面这篇文章:# 几种常见GC简介

-gcmetacapacity

此方法专门用于查看元空间的大小和使用情况,同时带有GC统计。此处我说的元空间是jdk1.8后提出的,在之前它叫做方法区,也就是我前面一直提到方法区的原因。

[root@hecs-402944 ~]# jstat -gcmetacapacity 21203 1000 3
   MCMN       MCMX        MC       CCSMN      CCSMX       CCSC     YGC   FGC    FGCT     GCT   
       0.0  1105920.0    64424.0        0.0  1048576.0     7856.0    11     6    0.516    0.635
       0.0  1105920.0    64424.0        0.0  1048576.0     7856.0    11     6    0.516    0.635
       0.0  1105920.0    64424.0        0.0  1048576.0     7856.0    11     6    0.516    0.635

前面看下来的话,上面的含义应该都知道了,不在单独介绍了。

-gcnew

年轻代内存使用和GC统计

[root@hecs-402944 ~]# jstat -gcnew 21203 1000 3
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT  
18944.0 18944.0    0.0 10129.0 11  15 18944.0 311296.0  54345.2     11    0.119
18944.0 18944.0    0.0 10129.0 11  15 18944.0 311296.0  54345.2     11    0.119
18944.0 18944.0    0.0 10129.0 11  15 18944.0 311296.0  54345.2     11    0.119

下面是未出现过的参数:

  • TT 对象在年轻代存活的次数
  • MTT 对象在年轻代存活的最大次数
  • DSS 期望幸存者区大小(幸存者区有两个,大小相同)

-gcnewcapacity

新生代内存使用统计,及GC统计

[root@hecs-402944 ~]# jstat -gcnewcapacity 21203 1000 3
  NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC 
  349184.0   349184.0   349184.0 116224.0  18944.0 116224.0  18944.0   348160.0   311296.0    11     6
  349184.0   349184.0   349184.0 116224.0  18944.0 116224.0  18944.0   348160.0   311296.0    11     6
  349184.0   349184.0   349184.0 116224.0  18944.0 116224.0  18944.0   348160.0   311296.0    11     6
  • NGC 年轻代大小

-gcold

老年代的内存使用,也有元空间的内存使用,同时又GC统计

[root@hecs-402944 ~]# jstat -gcold 21203 1000 3
   MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT   
 64424.0  60536.1   7856.0   7158.9    699392.0     17807.7     11     6    0.516    0.635
 64424.0  60536.1   7856.0   7158.9    699392.0     17807.7     11     6    0.516    0.635
 64424.0  60536.1   7856.0   7158.9    699392.0     17807.7     11     6    0.516    0.635

-gcoldcapacity

老年代内存空间使用统计,提供GC统计

[root@hecs-402944 ~]# jstat -gcoldcapacity 21203 1000 3
   OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT   
   699392.0    699392.0    699392.0    699392.0    11     6    0.516    0.635
   699392.0    699392.0    699392.0    699392.0    11     6    0.516    0.635
   699392.0    699392.0    699392.0    699392.0    11     6    0.516    0.635
  • OGC 老年代大小

-gcutil

GC统计,基本算是最常用的命令。其中的含义在前面都提到过,下面不在详细介绍了。

[root@hecs-402944 ~]# jstat -gcutil 21203 1000 3
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00  53.47  17.52   2.55  93.97  91.13     11    0.119     6    0.516    0.635
  0.00  53.47  17.52   2.55  93.97  91.13     11    0.119     6    0.516    0.635
  0.00  53.47  17.52   2.55  93.97  91.13     11    0.119     6    0.516    0.635

-printcompilation

编译方法统计,不常用

[root@hecs-402944 ~]# jstat -printcompilation 21203 1000 3
Compiled  Size  Type Method
    9267     59    1 org/springframework/web/method/support/HandlerMethodArgumentResolverComposite <init>
    9267     59    1 org/springframework/web/method/support/HandlerMethodArgumentResolverComposite <init>
    9267     59    1 org/springframework/web/method/support/HandlerMethodArgumentResolverComposite <init>
  • Compiled 编译数量
  • Size 编译大小
  • Type 编译类型
  • Method 编译方法

总结

全部可以使用的参数都介绍过了,其中最有用的是如下的两个:

  • -gcutil 实时统计GC数量
  • -gccause 查看GC的原因,用于分析问题