JDK神器之jstat(虚拟机统计信息监控工具)

背景介绍

jstat(JVM Statistics Monitorning Tool)用于监控虚拟机各种运行状态信息的命令行工具。

它可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,它是运行期定位虚拟机性能问题的首选工具。

语法:

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

参数 interval 和 count 代表查询间隔和次数,如果省略这两个参数,说明只查询一次。建设需要每250毫秒查询一次进程2764垃圾收集的情况,一共查询20次,那么命令应该是:jstat -gc 2764 250 20

指令使用

主要选项

选项作用
-class监视类装载、卸载数量、中空间及类装载所耗费的时间
-gc监视Java堆状况,包括Eden区、2个Survivor区、老年代、永久代等容量、已用空间、GC合计时间等信息
-gccapacity监视内容与-gc基本相同,但输出主要关注java堆各区域使用到的最大和最小空间
-gcutil监控内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比
-gccause与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因
-gcnew监视新生代GC的状况
-gcnewcapacity监视内容与-gcnew基本相同,输出主要关注使用到的最大和最小空间
-gcold监视老年代GC的状况
-gcoldcapacity监视内容与-gcold基本相同,输出主要关注使用到的最大和最小空间
-gcpermcapacity输出永久代使用到的最大和最小空间
-compiler输出JIT编译器编译过的方法、耗时等信息
-printcompilation输出已被JIT编译的方法

统计加载类的信息

命令:jstat -class 2548 (2548是jps -l 查询出来的)

C:\Users\kino>jstat -class 2548
Loaded  Bytes  Unloaded  Bytes     Time
  9075 17227.2        0     0.0       9.20
列名说明
Loaded装载的类的数量
Bytes装载类所占用的字节数
Unloaded卸载类的数量
Bytes卸载类所占用的字节数
Time装载类和卸载类所耗费的时间(毫秒)

编译统计

命令:jstat -compiler

C:\Users\kino>jstat -compiler 2548
Compiled Failed Invalid   Time   FailedType FailedMethod
    5519      1       0     2.34          1 sun/misc/ProxyGenerator generateClassFile
    列名说明
    Compiled编译任务执行数量
    Failed编译任务执行失败的数量
    Invalid编译任务失效的数量
    Time编译总耗时(毫秒)
    FailedType最后一个编译失败任务的类型
    FailedMethod最后一个编译失败任务所在的类及方法

    垃圾回收统计

    命令:jstat -gc

    C:\Users\kino>jstat -gc 2548
     S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
    16384.0 12288.0  0.0   12280.4 185856.0 21228.7   177152.0   35522.5   51032.0 47940.9 6784.0 6132.6      9    0.103   2      0.101    0.204
    列名说明
    S0C年轻代中第一个survior(幸存区)的容量(kb)
    S1C年轻代中第二个survior(幸存区)的容量(kb)
    S0U年轻代中第一个survior(幸存区)目前已使用的容量(kb)
    S1U年轻代中第二个survior(幸存区)目前已使用的容量(kb)
    ECeden区的容量(kb)
    EUeden区目前已使用的容量(kb)
    OC老年代的容量(kb)
    OU老年代目前已使用的容量(kb)
    PCperm永久代的容量(kb)
    PUperm永久代目前已使用的容量(kb)
    YGC从应用程序启动到采集时年轻代中gc次数
    YGCT从应用程序启动到采集时年轻代中gc所用时间(秒)
    FGC从应用程序启动到采集时老年代中gc次数
    FGCT从应用程序启动到采集时老年代gc所用的时间(秒)
    GCT从应用程序启动到采集时gc所用的总时间(秒)

    统计gc信息

    命令:jstat -gcutil

    C:\Users\kino>jstat -gcutil 2548
      S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
      0.00  99.94  12.67  20.05  93.94  90.40      9    0.103     2    0.101    0.204
    
      列名说明
      S0年轻代中第一个(survisor)幸存区已使用的容量占比
      S1年轻代中第二个(survisor)幸存区已使用的容量占比
      E伊旬园(eden)区已使用的容量占比
      O老年代区已使用的容量占比
      P永久代(perm)已使用的容量占比
      YGC年轻代到目前gc次数
      YGCT年轻代到目前gc耗费的总时间(秒)
      FGC老年代目前gc次数
      FGCT老年代目前gc耗费的总时间(秒)
      GC从应用程序到目前gc总耗时(秒)

      堆内存统计

      命令:jstat -gccapacity

      C:\Users\kino>jstat -gccapacity 2548
       NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC
       86528.0 1382400.0 264704.0 16384.0 12288.0 185856.0   173568.0  2764800.0   177152.0   177152.0      0.0 1093632.0  51032.0      0.0 1048576.0   6784.0      9     2
        列名说明
        NGCMN年轻代(young)中初始化(最小)的大小(kb)
        NGCMX年轻代(young)中初始化(最大)的大小(kb)
        NGC年轻代(young)中当前的容量(kb)
        S0C年轻代中第一个(survisor)幸存区的容量(kb)
        S1C年轻代中第二个(survisor)幸存区的容量(kb)
        EC年轻代中(Eden)伊旬园的容量(kb)
        OGCMN老年代(old)中初始化(最小)的容量(kb)
        OGCMX老年代(old)中初始化(最大)的容量(kb)
        OGC当前老年代的大小(kb)
        OC当前老年代的大小(kb)
        PGCMN永久代(perm)中初始化(最小)的大小(kb)
        PGCMX永久代(perm)中初始化(最大)的大小(kb)
        PGC永久代当前的大小(kb)
        PC永久代当前的大小(kb)
        YGC从应用程序启动到采集时年轻代gc的次数
        FGC从应用程序启动带采集时老年代gc的次数

        新生代垃圾回收统计

        命令:jstat -gcnew

        C:\Users\kino>jstat -gcnew 2548
         S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
        16384.0 12288.0    0.0 12280.4  8  15 16384.0 185856.0  24481.2      9    0.103
          列名说明
          S0C年轻代中第一个(survisor)幸存区的容量(kb)
          S1C年轻代中第二个(survisor)幸存区的容量(kb)
          S0U年轻代中第一个(survisor)幸存区目前已使用的容量(kb)
          S1U年轻代中第二个(survisor)幸存区目前已使用的容量(kb)
          TT对象在新生代中存活的次数
          MTT对象在新生代中存活的最大次数
          DSS当前需要survivor(幸存区)的容量 (kb)
          EC伊旬园(eden)区的大小(kb)
          EU伊旬园(eden)区已使用的大小(kb)
          YGC到目前年轻代gc的次数
          YGCT到目前年轻代gc所耗费的时间(秒)

          新生代内存统计

          命令:jstat -gcnewcapacity

          C:\Users\kino>jstat -gcnewcapacity 2548
            NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC
             86528.0  1382400.0   264704.0 460800.0  16384.0 460800.0  12288.0  1381376.0   185856.0     9     2
          
            列名说明
            MGCMN年轻代中初始化最小容量(kb)
            MGCMX年轻代中初始化最大容量(kb)
            NGC年轻代当前容量(kb)
            S0CMX年轻代第一个幸存区(survisor)最大容量(kb)
            S0C年轻代第一个幸存区(survisor)当前容量(kb)
            S1CMX年轻代第二个幸存区(survisor)最大容量(kb)
            S1C年轻代第二个幸存区(survisor)当前容量(kb)
            ECMX年轻代伊旬园区(Eden)最大容量(kb)
            EC年轻代伊旬园区(Eden)当前容量(kb)
            YGC截止到目前年轻代gc次数
            FGC截止到目前老年代gc次数

            老年代垃圾回收统计

            命令:jstat -gcold

            C:\Users\kino>jstat -gcold 2548
               MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT
             51032.0  47940.9   6784.0   6132.6    177152.0     35522.5      9     2    0.101    0.204
              列名说明
              PC永久区(perm)容量(kb)
              PU永久区(perm)已使用容量(kb)
              OC老年代容量(kb)
              OU老年代已使用容量(kb)
              YGC截止到目前年轻代gc次数
              FGC截止到目前老年代gc次数
              GCT截止到目前gc耗费的总时间(秒)

              老年代内存统计

              命令:jstat -gcoldcapacity

              C:\Users\kino>jstat -gcoldcapacity 2548
                 OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT
                 173568.0   2764800.0    177152.0    177152.0     9     2    0.101    0.204
                列名说明
                OGCMN老年代最小容量(kb)
                OGCMX老年代最大容量(kb)
                OGC老年代目前生成的容量(kb)
                OC老年代目前容量(kb)
                YGC截止到目前年轻代gc次数
                FGC截止到目前老年代gc次数
                FGCT截止到目前老年代gc耗费的总时间(秒)
                GCT截止到目前gc耗费的总时间(秒)


                最近二次gc统计

                命令:gstat -gccause

                C:\Users\kino>jstat -gccause 2548
                  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT    LGCC                 GCC              
                  0.00  99.94  13.92  20.05  93.94  90.40      9    0.103     2    0.101    0.204 Allocation Failure   No GC            
                  列名说明
                  LGCC最近垃圾回收的原因
                  GCC当前垃圾回收的原因

                  JVM编译方法统计

                  命令:jstat -printcompilation 

                  C:\Users\kino>jstat -printcompilation  2548
                  Compiled  Size  Type Method
                      5552    374    1 java/util/concurrent/ThreadPoolExecutor runWorker
                  列名说明
                  Compiled最近编译方法的数量
                  Size最近编译方法的字节码数量
                  Type最近编译方法的编译类型
                  Method方法名标识

                   项目实践场景

                  性能调优

                  • 监控堆内存使用情况
                    jstat 可以提供堆内存各个区域(如新生代、老年代、永久代 / 元空间)的使用量和占用率等信息。例如,使用命令 jstat -gc <pid> 1000 5 可以每隔 1 秒输出一次指定进程 ID(<pid>)的 JVM 垃圾回收统计信息,共输出 5 次。通过分析这些数据,开发者可以判断内存分配是否合理,是否存在内存泄漏的迹象。如果发现老年代内存持续增长且没有下降趋势,可能意味着存在对象无法被正常回收,需要进一步排查代码中是否存在持有对象引用导致垃圾回收器无法回收的情况。
                  • 分析垃圾回收性能
                    该工具能展示垃圾回收的次数、耗时等关键指标。通过观察这些数据,开发者可以评估垃圾回收器的性能。比如,频繁的新生代垃圾回收可能表示新生代内存分配过小,导致对象很快就被填满;而长时间的老年代垃圾回收则可能暗示老年代存在大量难以回收的对象。基于这些分析结果,开发者可以调整 JVM 的堆内存大小、垃圾回收器类型等参数,以优化应用程序的性能。

                  故障排查

                  • 定位内存溢出问题
                    当应用程序出现内存溢出错误时,jstat 可以帮助开发者快速了解内存使用的变化趋势。在错误发生前后一段时间内,持续使用 jstat 监控内存信息,对比不同时刻的内存使用情况,找出内存增长异常的区域,从而定位可能导致内存溢出的代码段。例如,如果发现元空间的使用量不断增加,可能是因为代码中动态生成了大量的类,需要检查是否存在类加载器泄漏或反射调用过多的问题。
                  • 检测线程阻塞问题
                    虽然 jstat 本身不直接提供线程阻塞的信息,但通过监控垃圾回收的情况可以间接推断线程是否存在阻塞问题。如果垃圾回收时间过长,可能是因为某些线程持有了锁,导致垃圾回收器无法正常工作,从而影响了应用程序的性能。结合其他工具(如 jstack)可以进一步定位具体的阻塞线程和代码位置。

                  资源规划

                  • 评估系统资源需求
                    在开发和部署新的 Java 应用程序时,使用 jstat 对现有类似应用程序进行监控,可以了解其在不同负载下的内存使用和垃圾回收情况。根据这些数据,开发者可以合理规划新应用程序所需的系统资源,包括内存、CPU 等,避免资源浪费或不足的情况发生。例如,如果监控发现某个应用程序在高负载下需要较大的堆内存才能保证稳定运行,那么在部署新应用时就可以适当增加堆内存的分配。
                  • 优化服务器配置
                    对于运行多个 Java 应用程序的服务器,通过 jstat 监控各个应用程序的资源使用情况,可以合理调整服务器的配置,实现资源的最优分配。例如,如果发现某个应用程序的内存使用量较低,而另一个应用程序经常出现内存紧张的情况,可以考虑调整它们的堆内存分配比例,以提高服务器的整体性能。

                  服务稳定性保障

                  • 实时监控应用状态
                    在生产环境中,可以使用 jstat 实时监控 Java 应用程序的运行状态。通过设置监控脚本,定期收集和分析 jstat 输出的数据,一旦发现内存使用或垃圾回收出现异常情况,及时发出警报,通知运维人员进行处理。这样可以在问题发生之前及时采取措施,避免应用程序出现故障,保障服务的稳定性。
                  • 验证系统变更效果
                    在对 JVM 参数进行调整、更新应用程序代码或进行其他系统变更后,使用 jstat 监控变更前后的性能指标,可以验证变更是否达到了预期的效果。如果变更后内存使用更加合理、垃圾回收频率降低,说明变更起到了积极的作用;反之,则需要进一步分析原因并进行调整。

                  评论
                  添加红包

                  请填写红包祝福语或标题

                  红包个数最小为10个

                  红包金额最低5元

                  当前余额3.43前往充值 >
                  需支付:10.00
                  成就一亿技术人!
                  领取后你会自动成为博主和红包主的粉丝 规则
                  hope_wisdom
                  发出的红包

                  打赏作者

                  十五001

                  你的鼓励将是我创作的最大动力

                  ¥1 ¥2 ¥4 ¥6 ¥10 ¥20
                  扫码支付:¥1
                  获取中
                  扫码支付

                  您的余额不足,请更换扫码支付或充值

                  打赏作者

                  实付
                  使用余额支付
                  点击重新获取
                  扫码支付
                  钱包余额 0

                  抵扣说明:

                  1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
                  2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

                  余额充值