java工具系列-jstat
2016-11-03 本文已影响0人
allanYan
概览
JDK本身提供了很多工具,用于监控JVM和java程序的运行状况;Jstat可以查看虚拟机的GC,类加载等信息,可以通过jstat -options查看其支持的选项,在JDK7下,其支持的选项如下:
options.png运行方式
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
监控本地JVM没什么特殊的,通过jps查找到java进程ID,即可直接运行,例如:
jstat -list 34673 #list counter names
jstat -name java.ci.totalTime 34673 #output counters matching given pattern
jstat -snap -v 34673
jstat -class 34673
如果想要监控远程的JVM,则必须在远程服务器上启动RMI服务;
- 在远程服务器上建立jstatd.all.policy文件,内容为:
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.util.PropertyPermission "java.rmi.server.ignoreSubClasses", "write";
permission java.util.PropertyPermission "sun.jvmstat.monitor.*", "read";
permission java.util.PropertyPermission "java.io.tmpdir", "read";
permission java.lang.RuntimePermission "accessClassInPackage.sun.tools.jstatd";
permission java.lang.RuntimePermission "accessClassInPackage.sun.jvmstat.*";
permission java.io.FilePermission "/tmp","read";
permission java.io.FilePermission "/tmp/-","read";
permission java.io.FilePermission "/tmp/*","read";
permission java.net.SocketPermission "127.0.0.1:9090","connect,resolve";
permission java.net.SocketPermission "127.0.0.1:1024-", "accept,resolve";
};
简单点,可以赋予所有权限:
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
- 在远程服务器启动RMI Registry服务:
jstatd -p 9090 -J-Djava.security.policy=jstatd.all.policy
此处指定Registry服务的端口为9090,也可不指定,默认为1099;
当然此处的端口需要与jstatd.all.policy中的端口保持一致。
数据来源
jstat统计的数据来源是哪呢?查看源码可以发现虚拟机会在tmp目录下为每个进程建立文件,文件的名称为进程ID,目录名前缀为hsperfdata_;具体的实现可以参考sun.jvmstat.perfdata.monitor.protocol.local.PerfDataFile
通过如下命令:
java -XX:+PrintFlagsInitial|grep Perf
或
java -XX:PrintFlagsFinal -version|grep Perf
可以看到和PerfData相关的配置项和默认值如下:
bool PerfAllowAtExitRegistration = false
bool PerfBypassFileSystemCheck = false
intx PerfDataMemorySize = 32768
intx PerfDataSamplingInterval = 50
ccstr PerfDataSaveFile =
bool PerfDataSaveToFile = false
bool PerfDisableSharedMem = false
intx PerfMaxStringConstLength = 1024
bool UsePerfData = true
- UsePerfData:如果关闭了UsePerfData这个参数,那么jvm启动过程中perf memory不会被创建;
- PerfDisableSharedMem:存储PerfData的内存是否禁止共享,不管这个参数是否设置,jvm在启动的时候都会分配一块内存来存放PerfData,只是说这个PerfData是不是其他进程可见的问题,如果设置为true,依赖PerfData的jps、jstat等都无法工作。
选项说明
class
class.png- Loaded: 加载的类的数量
- Bytes: 加载的类占有的内存
- Unloaded: 被卸载的类的数量
- Bytes:被卸载的类占有的内存
- Time: 类加载耗费的时间
compiler
compiler.png- Compiler:JIT编译执行次数
- Failed:编译失败次数
- Invalid:无效的编译次数
- Time:编译耗费时间
- FailedType:最近一次编译失败类型
- FailedMethod:最近编译失败的类和方法
gc
gc.png- S0C: survivor 0当前容量
- S1C: survivor 1当前容量
- S0U: survivor 0已使用空间
- S1U:survivor 1已使用空间
- EC: eden当前容量
- EU: eden已使用空间
- OC:old当前容量
- OU:old已使用空间
- PC:perm区当前容量
- PU:perm区已使用空间
- YGC: yong GC发生次数
- YGCT: yong GC耗费时间
- FGC: full GC发生次数
- FGCT:full GC耗费时间
- GCT: GC耗费总时间(yong gc time+full gc time)
gccapacity
gccapacity.png- NGCMN: 新生代最小容量
- NGCMX: 新生代最大容量
- NGC: 新生代当前容量
- S0C: survivor 0当前容量
- S1C: survivor 1当前容量
- EC: eden区当前容量
- OGCMN: 老年代最小容量
- OGCMX: 老年代最大容量
- OGC: 老年代当前容量(Old Generation Capacity -Current)
- OC:old区当前容量(Old Space Capacity-Current)
- PGCMN: perm区最小容量
- PGCMX:perm区最大容量
- PGC:永久代当前容量
- PC: perm区当前容量
- YGC:yong gc次数
- FGC: full gc次数
gccause
gccause.png- S0: survivor 0使用百分比;
- S1: survivor 1使用百分比;
- E: eden使用百分比;
- O: old使用百分比;
- P: perm使用百分比;
- YGC:yong gc次数
- YGCT:yong gc耗费时间
- FGC:full gc次数
- FGCT: full gc耗费时间
- GCT: gc耗费总时间
- LGCC:上一次gc原因
- GCC:当前gc原因
gcnew
gcnew.png- S0C: survivor 0当前容量
- S1C: survivor 1当前容量
- S0U:survivor 0已使用容量
- S1U:survivor 1已使用容量
- TT: Tenuring threshold,可通过参数-XX:PretenureSizeThreshold进行设置;虚拟机采用了分代收集的思想来管理内存,给每个对象定义了一个对象年龄计数器。如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到survivor空间,并将对象年龄设为1。对象在survivor区中每熬过一次Minor GC,年龄就增加1;当它的年龄增加到一定程度时(默认为15),就会被晋升到老年代中。那分代年龄存放在哪呢?实际上内存中的每个对象都有对象头,包括Mark Word(标记字段)和 Klass Pointer(类型指针;分代年龄就存放在Mark Word中。
- MTT:Max Tenuring threshold,可通过参数-XX:MaxTenuringThreshold进行设置
- DSS:Desired survivor size (KB),假设MTT为15,如果Yong GC时发现所有年龄对象容量小于DSS,则将年龄设置为MTT;
- EC: eden当前容量
- EU: eden已使用容量
- YGC: yong gc发生次数
- YGCT: yong gc耗费总时间
gcnewcapacity
Paste_Image.png- NGCMN: 新生代最小容量;
- NGCMX: 新生代最大容量;
- NGC: 新生代当前容量;
- S0CMX: survivor 0最大容量
- S0C:survivor 0当前容量
- S1CMX: survivor 1最大容量
- S1C:survivor 1当前容量
- ECMX: eden区最大容量
- EC : eden区当前容量
- YGC: yong gc次数
- FGC: full gc次数
gcold
Paste_Image.png- PC: perm区当前容量
- PU:perm区已使用容量
- OC: old区当前容量
- OU: old区已使用容量
- YGC: yong gc次数
- FGC: full gc次数
- FGCT:full gc 耗费时间
- GCT:gc耗费总时间
gcoldcapacity
gcoldcapacity.png- OGCMN: 老年代最大容量
- OGCMX: 老年代最小容量
- OGC: 老年代当前容量
- OC: old区当前容量
- YGC: yong gc次数
- FGC: full gc次数
- FGCT: full gc耗费时间
- GCT: gc耗费总时间
gcpermcapacity
gcpermcapacity.png- PGCMN: 永久代最小容量
- PGCMX: 永久代最大容量
- PGC: 永久代当前容量
- PC: perm区当前容量
- YGC:yong gc 次数
- FGC: full gc次数
- FGCT: full gc时间
- GCT: gc耗费总时间
gcutil
Paste_Image.png- S0: survivor 0已使用百分比
- S1:survivor 1已使用百分比
- E: eden已使用百分比
- O:old区已使用百分比
- P: perm区已使用百分比
- YGC:yong gc次数
- YGCT:yong gc时间
- FGC:full gc次数
- FGCT:full gc时间
- GCT: gc耗费总时间
printcompilation
printcompilation.png- Compiled:编译次数
- Size:上次编译代码大小
- Type:上次编译类型
- Method: 上次编译的类和方法