java工具系列-jstat

概览

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
jstat -J-Djstat.showUnsupported=true -snap 34673 # 查看完整的信息

如果想要监控远程的JVM,则必须在远程服务器上启动RMI服务;

  1. 在远程服务器上建立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;  
};  
  1. 在远程服务器启动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       
  1. UsePerfData:如果关闭了UsePerfData这个参数,那么jvm启动过程中perf memory不会被创建;
  2. PerfDisableSharedMem:存储PerfData的内存是否禁止共享,不管这个参数是否设置,jvm在启动的时候都会分配一块内存来存放PerfData,只是说这个PerfData是不是其他进程可见的问题,如果设置为true,依赖PerfData的jps、jstat等都无法工作。

选项说明

class

class.png
  1. Loaded: 加载的类的数量
  2. Bytes: 加载的类占有的内存
  3. Unloaded: 被卸载的类的数量
  4. Bytes:被卸载的类占有的内存
  5. Time: 类加载耗费的时间

compiler

compiler.png
  1. Compiler:一共进行了多少次编译任务。一次“编译任务”(CompileTask)对应一个顶层方法的编译;一个Java方法可能出于不同原因会多次被JIT编译;
  2. Failed:在执行了的编译任务中,有多少个编译失败了。JIT编译器可能会出于一些限制条件,或者是未修复的bug,而决定在编译过程中中止该编译任务。这种行为叫做编译器的bailout。举例来说,C2在编译过程中如果发现被编译的方法经过优化后有无限空循环的话,就会决定中止编译并bailout,这属于限制条件;C2在做了某些优化后发现IR的形状不对了,为了避免bug而决定中止编译并bailout,这属于规避未修复的bug;注意:这并不是deoptimization。
  3. Invalid:在已经执行的编译任务中,有多少在编译完成后未能被安装到CodeCache中。这通常是由于HotSpot VM的JIT编译是后台并发进行的,在编译过程中Java程序还可能边执行边触发新的类加载,而新的类加载可能会导致正在进行的JIT编译在刚开始所做的激进假设到编译完成的时候已经不成立了(例如说某个编译任务在JIT编译刚开始的时候假设抽象基类Base只有一个具体派生类Foo,但一边编译一边有新的Base派生类Bar给加载了进来)
  4. Time:编译耗费时间
  5. FailedType:最近一个编译失败的编译任务的失败原因代号;
  6. FailedMethod:最近一个编译失败的编译任务是哪个Java方法

FailedType具体的字段含义如下:

 // Compile type Information for print_last_compile() and CompilerCounters
  enum { no_compile, normal_compile, osr_compile, native_compile };

0:no_compile:没在编译
1:normal_compile:普通编译(从方法正常入口开始编译)
2:osr_compile:On-Stack Rreplacement编译(从方法中某个循环的回边开始编译)
3:native_compile:native wrapper的编译

gc

gc.png
  1. S0C: survivor 0当前容量
  2. S1C: survivor 1当前容量
  3. S0U: survivor 0已使用空间
  4. S1U:survivor 1已使用空间
  5. EC: eden当前容量
  6. EU: eden已使用空间
  7. OC:old当前容量
  8. OU:old已使用空间
  9. PC:perm区当前容量
  10. PU:perm区已使用空间
  11. YGC: yong GC发生次数
  12. YGCT: yong GC耗费时间
  13. FGC: full GC发生次数
  14. FGCT:full GC耗费时间
  15. GCT: GC耗费总时间(yong gc time+full gc time)

gccapacity

gccapacity.png
  1. NGCMN: 新生代最小容量
  2. NGCMX: 新生代最大容量
  3. NGC: 新生代当前容量
  4. S0C: survivor 0当前容量
  5. S1C: survivor 1当前容量
  6. EC: eden区当前容量
  7. OGCMN: 老年代最小容量
  8. OGCMX: 老年代最大容量
  9. OGC: 老年代当前容量(Old Generation Capacity -Current)
  10. OC:old区当前容量(Old Space Capacity-Current)
  11. PGCMN: perm区最小容量
  12. PGCMX:perm区最大容量
  13. PGC:永久代当前容量
  14. PC: perm区当前容量
  15. YGC:yong gc次数
  16. FGC: full gc次数

gccause

gccause.png
  1. S0: survivor 0使用百分比;
  2. S1: survivor 1使用百分比;
  3. E: eden使用百分比;
  4. O: old使用百分比;
  5. P: perm使用百分比;
  6. YGC:yong gc次数
  7. YGCT:yong gc耗费时间
  8. FGC:full gc次数
  9. FGCT: full gc耗费时间
  10. GCT: gc耗费总时间
  11. LGCC:上一次gc原因
  12. GCC:当前gc原因

gcnew

gcnew.png
  1. S0C: survivor 0当前容量
  2. S1C: survivor 1当前容量
  3. S0U:survivor 0已使用容量
  4. S1U:survivor 1已使用容量
  5. TT: Tenuring threshold,可通过参数-XX:PretenureSizeThreshold进行设置;虚拟机采用了分代收集的思想来管理内存,给每个对象定义了一个对象年龄计数器。如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到survivor空间,并将对象年龄设为1。对象在survivor区中每熬过一次Minor GC,年龄就增加1;当它的年龄增加到一定程度时(默认为15),就会被晋升到老年代中。那分代年龄存放在哪呢?实际上内存中的每个对象都有对象头,包括Mark Word(标记字段)和 Klass Pointer(类型指针;分代年龄就存放在Mark Word中。
  6. MTT:Max Tenuring threshold,可通过参数-XX:MaxTenuringThreshold进行设置
  7. DSS:Desired survivor size (KB),假设MTT为15,如果Yong GC时发现所有年龄对象容量小于DSS,则将年龄设置为MTT;
  8. EC: eden当前容量
  9. EU: eden已使用容量
  10. YGC: yong gc发生次数
  11. YGCT: yong gc耗费总时间

gcnewcapacity

Paste_Image.png
  1. NGCMN: 新生代最小容量;
  2. NGCMX: 新生代最大容量;
  3. NGC: 新生代当前容量;
  4. S0CMX: survivor 0最大容量
  5. S0C:survivor 0当前容量
  6. S1CMX: survivor 1最大容量
  7. S1C:survivor 1当前容量
  8. ECMX: eden区最大容量
  9. EC : eden区当前容量
  10. YGC: yong gc次数
  11. FGC: full gc次数

gcold

Paste_Image.png
  1. PC: perm区当前容量
  2. PU:perm区已使用容量
  3. OC: old区当前容量
  4. OU: old区已使用容量
  5. YGC: yong gc次数
  6. FGC: full gc次数
  7. FGCT:full gc 耗费时间
  8. GCT:gc耗费总时间

gcoldcapacity

gcoldcapacity.png
  1. OGCMN: 老年代最大容量
  2. OGCMX: 老年代最小容量
  3. OGC: 老年代当前容量
  4. OC: old区当前容量
  5. YGC: yong gc次数
  6. FGC: full gc次数
  7. FGCT: full gc耗费时间
  8. GCT: gc耗费总时间

gcpermcapacity

gcpermcapacity.png
  1. PGCMN: 永久代最小容量
  2. PGCMX: 永久代最大容量
  3. PGC: 永久代当前容量
  4. PC: perm区当前容量
  5. YGC:yong gc 次数
  6. FGC: full gc次数
  7. FGCT: full gc时间
  8. GCT: gc耗费总时间

gcutil

Paste_Image.png
  1. S0: survivor 0已使用百分比
  2. S1:survivor 1已使用百分比
  3. E: eden已使用百分比
  4. O:old区已使用百分比
  5. P: perm区已使用百分比
  6. YGC:yong gc次数
  7. YGCT:yong gc时间
  8. FGC:full gc次数
  9. FGCT:full gc时间
  10. GCT: gc耗费总时间

printcompilation

printcompilation.png
  1. Compiled:编译次数
  2. Size:上次编译代码大小
  3. Type:上次编译类型
  4. Method: 上次编译的类和方法
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容