《深入理解java虚拟机》之java工具-jstat

原文章链接:https://www.cnblogs.com/kongzhongqijing/articles/3625574.html

 

jstat(JVM Statistics Monitoring Tool)是用于监控虚拟机各种运行状态信息的命令行工具。他可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形的服务器上,它是运行期定位虚拟机性能问题的首选工具。

一、介绍

用以判断JVM是否存在内存问题呢?如何判断JVM垃圾回收是否正常?一般的top指令基本上满足不了这样的需求,因为它主要监控的是总体的系统资源,很难定位到java应用程序。

 

Jstat是JDK自带的一个轻量级小工具。全称“Java Virtual Machine statistics monitoring tool”,它位于java的bin目录下,主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。可见,Jstat是轻量级的、专门针对JVM的工具,非常适用。由于JVM内存设置较大,图中百分比变化不太明显。

 

它是一个极强的监视VM内存工具。可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量。工具特别强大,有众多的可选项,详细查看堆内各个部分的使用量,以及加载类的数量。使用时,需加上查看进程的进程id,和所选参数。

 

二、参数及用法

 

执行:cd $JAVA_HOME/bin中执行jstat,注意jstat后一定要跟参数。

语法结构:

Usage: jstat -help|-options

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

 

参数解释:

Options — 选项,我们一般使用 -gcutil 查看gc情况

vmid    — VM的进程号,即当前运行的java进程号

interval– 间隔时间,单位为秒或者毫秒

count   — 打印次数,如果缺省则打印无数次

参数interval和count代表查询间隔和次数,如果省略这两个参数,说明只查询一次。假设需要每250毫秒查询一次进程5828垃圾收集状况,一共查询5次,那命令行如下:

jstat -gc 5828 250 5

对于命令格式中的VMIDLVMID需要特别说明下:如果是本地虚拟机进程,VMID(Virtual Machine IDentifier,虚机标识符)和LVMID(Local Virtual Machine IDentifier,虚机标识符)是一致的,如果是远程虚拟机进程,那VMID的格式应当是:[protocol:][//] lvmid [@hostname[:port]/servername]

选项

选项option代表这用户希望查询的虚拟机信息,主要分为3类:类装载、垃圾收集和运行期编译状况,具体选项及作用如下:

常见的有 

  • l  class (类加载器) 
  • l  compiler (JIT) 
  • l  gc (GC堆状态) 
  • l  gccapacity (各区大小) 
  • l  gccause (最近一次GC统计和原因) 
  • l  gcnew (新区统计)
  • l  gcnewcapacity (新区大小)
  • l  gcold (老区统计)
  • l  gcoldcapacity (老区大小)
  • l  gcpermcapacity (永久区大小)
  • l  gcutil (GC统计汇总)
  • l  printcompilation (HotSpot编译统计)

 

    jstat -class pid:显示加载class的数量,及所占空间等信息。

    jstat -compiler pid:显示VM实时编译的数量等信息。

    jstat -gc pid:可以显示gc的信息,查看gc的次数,及时间。其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。

    jstat -gccapacity:可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小,如:PGCMN显示的是最小perm的内存使用量,PGCMX显示的是perm的内存最大使用量,PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。其他的可以根据这个类推, OC是old内纯的占用量。

    jstat -gcnew pid:new对象的信息。

    jstat -gcnewcapacity pid:new对象的信息及其占用量。

    jstat -gcold pid:old对象的信息。

    jstat -gcoldcapacity pid:old对象的信息及其占用量。

    jstat -gcpermcapacity pid: perm对象的信息及其占用量。

    jstat -util pid:统计gc信息统计。

    jstat -printcompilation pid:当前VM执行的信息。

    除了以上一个参数外,还可以同时加上 两个数字,如:jstat -printcompilation 3024 250 6是每250毫秒打印一次,一共打印6次,还可以加上-h3每三行显示一下标题。

 

三、实例使用

 

实例使用1:统计gc信息

《《深入理解java虚拟机》之java工具-jstat》

 

各列意义

S0C:年轻代中第一个存活区的大小

S1C:年轻代中第二个存活区的大小

S0U:年轻代中第一个存活区已使用的空间 (KB) 

S1U:年轻代中第二个存活区已使用的空间 (KB) 

EC:   Edem区大小

EU:   年轻代中Edem区已使用的空间 (KB) 

OC:  老年代大小

OU:  老年代已使用的空间 (KB) 

PC:   持久代大小

PU: 持久代已使用的空间 (KB) 

YGC: 从应用程序启动到采样时young gc的次数

YGCT: 从应用程序启动到采样时young gc的所用的时间(s)

FGC:  从应用程序启动到采样时full gc的次数

FGCT: 从应用程序启动到采样时full gc的所用的时间

GCT: 从应用程序启动到采样时整个gc所用的时间

 

如果young gc所用的时间比较长,如几秒几十秒,则肯定不正常。

 

# jstat -gcutil 25444

 S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
 
 11.63   0.00   56.46  66.92  98.49 162    0.248    6      0.331    0.579 

《《深入理解java虚拟机》之java工具-jstat》

 

实例使用2:(25444是java的进程号,ps -ef | grep java)

 

# jstat -gcutil 25444 1000 5 

 

各列意义

S0  — Heap上的 Survivor space 0 区已使用空间的百分比

S1  — Heap上的 Survivor space 1 区已使用空间的百分比

E   — Heap上的 Eden space 区已使用空间的百分比

O   — Heap上的 Old space 区已使用空间的百分比

P   — Perm space 区已使用空间的百分比

YGC — 从应用程序启动到采样时发生 Young GC 的次数

YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒)

FGC — 从应用程序启动到采样时发生 Full GC 的次数

FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒)

GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)

 

我们可以看到,5次young gc之后,垃圾内存被从Eden space区(E)放入了Old space区(O),并引起了百分比的变化,导致Survivor space使用的百分比从73.54%(S0)降到0%(S1)。有效释放了内存空间。绿框中,我们可以看到,一次full gc之后,Old space区(O)的内存被回收,从99.05%降到67.52%。

 

图中同时打印了young gc和full gc的总次数、总耗时。而,每次young gc消耗的时间,可以用相间隔的两行YGCT相减得到。每次full gc消耗的时间,可以用相隔的两行FGCT相减得到。例如红框中表示的第一行、第二行之间发生了1次young gc,消耗的时间为0.252-0.252=0.0秒。

 

常驻内存区(P)的使用率,始终停留在98.49%左右,说明常驻内存没有突变,比较正常。

 

如果young gc和full gc能够正常发生,而且都能有效回收内存,常驻内存区变化不明显,则说明java内存释放情况正常,垃圾回收及时,java内存泄露的几率就会大大降低。但也不能说明一定没有内存泄露。

 

GCT 是YGCT 和FGCT的时间总和。

 

以上,介绍了Jstat按百分比查看gc情况的功能。

 

其实,它还有功能,例如加载类信息统计功能、内存池信息统计功能等,那些是以绝对值的形式打印出来的,比较少用。

[root@localhost bin]# ps -ef | grep java

 

root     25917     1  2 23:23 pts/2    00:00:05 /usr/local/jdk1.5/bin/java -Djava.endorsed.dirs=/usr/local/jakarta-tomcat-5.0.30/common/endorsed -classpath /usr/local/jdk1.5/lib/tools.jar:/usr/local/jakarta-tomcat-5.0.30/bin/bootstrap.jar:/usr/local/jakarta-tomcat-5.0.30/bin/commons-logging-api.jar -Dcatalina.base=/usr/local/jakarta-tomcat-5.0.30 -Dcatalina.home=/usr/local/jakarta-tomcat-5.0.30 -Djava.io.tmpdir=/usr/local/jakarta-tomcat-5.0.30/temp org.apache.catalina.startup.Bootstrap start

 

实例使用3:jstat -class pid:显示加载class的数量,及所占空间等信息。

[root@localhost bin]# jstat -class 25917

 
Loaded  Bytes  Unloaded  Bytes     Time
 
2629    2916.8       29   24.6     0.90

Loaded 装载的类的数量 

Bytes 装载类所占用的字节数 

Unloaded 卸载类的数量 

Bytes 卸载类的字节数 

Time 装载和卸载类所花费的时间

 

实例使用4:jstat -compiler pid:显示VM实时编译的数量等信息

 

# jstat -compiler 25917

Compiled Failed Invalid   Time   FailedType FailedMethod
 
     768      0       0   0.70            0

Compiled 编译任务执行数量 

Failed 编译任务执行失败数量 

Invalid 编译任务执行失效数量 

Time 编译任务消耗时间 

FailedType 最后一个编译失败任务的类型 

FailedMethod 最后一个编译失败任务所在的类及方法

 实例使用5:jstat –gccapacity

jstat –gccapacity :可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小,如:PGCMN显示的是最小perm的内存使用量,PGCMX显示的是perm的内存最大使用量,PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。其他的可以根据这个类推, OC是old内纯的占用量。

# jstat -gccapacity 25917

《《深入理解java虚拟机》之java工具-jstat》

NGCMN       640.0
 
NGCMX       4992.0
 
NGC         832.0
 
S0C         64.0
 
S1C         64.0
 
EC          704.0
 
OGCMN       1408.0
 
OGCMX       60544.0
 
OGC         9504.0
 
OC          9504.0                  OC是old内纯的占用量
 
PGCMN       8192.0                  PGCMN显示的是最小perm的内存使用量
 
PGCMX       65536.0                 PGCMX显示的是perm的内存最大使用量
 
PGC         12800.0                 PGC是当前新生成的perm内存占用量
 
PC          12800.0                 PC是但前perm内存占用量
 
YGC         164
 
FGC         6

《《深入理解java虚拟机》之java工具-jstat》

 
NGCMN 年轻代(young)中初始化(最小)的大小(KB) 

NGCMX 年轻代(young)的最大容量 (KB) 

NGC 年轻代(young)中当前的容量 (KB) 

S0C 年轻代中第一个survivor(幸存区)的容量 (KB) 

S1C 年轻代中第二个survivor(幸存区)的容量 (KB) 

EC 年轻代中Eden(伊甸园)的容量 (KB) 

OGCMN old代中初始化(最小)的大小 (KB) 

OGCMX old代的最大容量(KB) 

OGC old代当前新生成的容量 (KB) 

OC Old代的容量 (KB)

PGCMN perm代中初始化(最小)的大小 (KB) 

PGCMX perm代的最大容量 (KB)
PGC perm代当前新生成的容量 (KB) 

PC Perm(持久代)的容量 (KB)

YGC 从应用程序启动到采样时年轻代中gc次数 

FGC 从应用程序启动到采样时old代(全gc)gc次数

 

 实例使用6:jstat -gcnew pid: new对象的信息

 

# jstat -gcnew 25917

 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
 
 64.0   64.0   47.4   0.0   2  15   32.0    704.0    145.7    168    0.254

S0C 年轻代中第一个survivor(幸存区)的容量 (KB) 

S1C 年轻代中第二个survivor(幸存区)的容量 (KB) 

S0U 年轻代中第一个survivor(幸存区)目前已使用空间 (KB) 

S1U 年轻代中第二个survivor(幸存区)目前已使用空间 (KB) 

TT 持有次数限制 MTT 最大持有次数限制 

EC 年轻代中Eden(伊甸园)的容量 (KB) 

EU 年轻代中Eden(伊甸园)目前已使用空间 (KB) 

YGC 从应用程序启动到采样时年轻代中gc次数 

YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)

 

 实例使用7:jstat -gcnewcapacity pid: new对象的信息及其占用量

# jstat -gcnewcapacity 25917

 NGCMN  NGCMX   NGC   S0CMX  S0C   S1CMX  S1C   ECMX    EC      YGC   FGC

640.0  4992.0  832.0 64.0   448.0 448.0  64.0   4096.0  704.0  168     6

NGCMN 年轻代(young)中初始化(最小)的大小(KB) 

NGCMX 年轻代(young)的最大容量 (KB) 

NGC 年轻代(young)中当前的容量 (KB) 

S0CMX 年轻代中第一个survivor(幸存区)的最大容量 (KB) 

S0C 年轻代中第一个survivor(幸存区)的容量 (KB) 

S1CMX 年轻代中第二个survivor(幸存区)的最大容量 (KB) 

S1C 年轻代中第二个survivor(幸存区)的容量 (KB) 

ECMX 年轻代中Eden(伊甸园)的最大容量 (KB) 

EC 年轻代中Eden(伊甸园)的容量 (KB) 

YGC 从应用程序启动到采样时年轻代中gc次数 

FGC 从应用程序启动到采样时old代(全gc)gc次数

 实例使用8:jstat -gcold pid: old对象的信息。

 

# jstat -gcold 25917

  PC       PU        OC          OU       YGC    FGC    FGCT     GCT
 
 12800.0  12617.6     9504.0      6561.3   169     6    0.335    0.591

PC Perm(持久代)的容量 (KB) 

PU Perm(持久代)目前已使用空间 (KB)

OC Old代的容量 (KB) 

OU Old代目前已使用空间 (KB) 

YGC 从应用程序启动到采样时年轻代中gc次数 

FGC 从应用程序启动到采样时old代(全gc)gc次数 

FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s) 

GCT从应用程序启动到采样时gc用的总时间(s)

 

实例使用9:jstat -gcoldcapacity pid:old对象的信息及其占用量。

 

[root@localhost bin]# jstat -gcoldcapacity 25917

OGCMN      OGCMX        OGC         OC       YGC   FGC    FGCT     GCT

1408.0     60544.0      9504.0      9504.0   169     6    0.335    0.591

OGCMN old代中初始化(最小)的大小 (KB) 

OGCMX old代的最大容量(KB)

OGC old代当前新生成的容量 (KB) 

OC Old代的容量 (KB) 

YGC 从应用程序启动到采样时年轻代中gc次数 

FGC 从应用程序启动到采样时old代(全gc)gc次数 

FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)

GCT从应用程序启动到采样时gc用的总时间(s)

 

 实例使用10:jstat -gcpermcapacity pid: perm对象的信息及其占用量。

 

# jstat -gcpermcapacity 25917

PGCMN      PGCMX       PGC         PC      YGC   FGC    FGCT     GCT
 
8192.0    65536.0    12800.0    12800.0   169     6    0.335    0.591

PGCMN perm代中初始化(最小)的大小 (KB) 

PGCMX perm代的最大容量 (KB)

PGC perm代当前新生成的容量 (KB) 

PC Perm(持久代)的容量 (KB)

YGC 从应用程序启动到采样时年轻代中gc次数 

FGC 从应用程序启动到采样时old代(全gc)gc次数 

FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s) 

GCT 从应用程序启动到采样时gc用的总时间(s)

 

实例使用11:jstat -printcompilation pid:当前VM执行的信息。

 

# jstat -printcompilation -h3  25917 1000 5

每1000毫秒打印一次,一共打印5次,还可以加上-h3每三行显示一下标题。

《《深入理解java虚拟机》之java工具-jstat》

Compiled  Size  Type Method
 
     788     73    1 java/io/File <init>
 
     788     73    1 java/io/File <init>
 
     788     73    1 java/io/File <init>
 
Compiled  Size  Type Method
 
     788     73    1 java/io/File <init>
 
     788     73    1 java/io/File <init>
 

《《深入理解java虚拟机》之java工具-jstat》

Compiled 编译任务的数目 

Size 方法生成的字节码的大小 

Type 编译类型 

Method 类名和方法名用来标识编译的方法。

类名使用/做为一个命名空间分隔符。方法名是给定类中的方法。上述格式是由-XX:+PrintComplation选项进行设置的

 

参考资料:

1、http://xueliang880107.iteye.com/blog/954073

2、http://blog.csdn.net/zhaozheng7758/article/details/8623549

    原文作者:java虚拟机
    原文地址: https://blog.csdn.net/lyzx_in_csdn/article/details/83418510
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞