jstat各种用法以及结果中每一列的详细含义描述 |
您所在的位置:网站首页 › 伊甸园的含义 › jstat各种用法以及结果中每一列的详细含义描述 |
全称“Java Virtual Machine statistics monitoring tool”(statistics 统计;monitoring 监控;tool 工具) 用于监控虚拟机的各种运行状态信息的命令行工具。 可以查看虚拟机中进程的类加载,内存,垃圾回收、jit编译等运行数据。 jstat 命令格式: jstat [-option] [vmid] [int s|ms] [count] 例如: jstat -class 64363 1s 10 简单解释: -class 是option的选项参数,要看类加载信息;64363是es的pid 1s 就是间隔一秒执行一次,10 就是执行10次 后面的执行时间和执行次数可以不写,那就默认执行一次。 可以看下面的-class选项的说明中的这个命令的执行效果图。 《深入理解Java虚拟机》上面弄的截图。 一眼望去,关于gc的选项很多,也说明实际现场出问题差不多都跟gc的STW时间太久导致程序间歇性死亡假死或者直接gg。比如es要是gc时间久了,就完蛋了。
下面分别看看,顺便亲自手动试试每个option命令(在jdk 1.8 的环境下测试的截图) 1, -class 监视类装载、卸载数量,总空间、类装载所耗费时间具体例子:jstat -class 64363 1s 10 查看es进程的类加载信息,es的pid是64363 ,间隔1s执行一次,一共执行10次。 elasticsearch的运行要加载一万两千多个类呢,还有unloaded 类。 这不是未加载的意思。 2,-compiler 输出jit编译器编译过的方法耗时等信息 jstat -compiler 64363 还是使用es的进程来搞实验,编译的数量是2万多,但是load的class数量才一万多,为什么? 我这么解释:把整个项目都给编译一遍,但是并不是所有的类都会被jvm加载。这么解释还凑合吧。 3,-printcompilation 输出已经被jit编译的方法 jstat -printcompilation 629756 额,我也不知道这个jit是干啥的,就摆个截图放这吧,这个不是es而是另一个消费kafka的进程的pid。 4,-gc 监视Java堆状况,eden,2个s区,old,元空间等容量,gc时间等情况 jstat -gc 64363 1s 100 看es进程的gc情况,一秒一刷执行100次,执行一次,遇不到gc 以下几个容量大小的单位都是 kb,包括后面的几个option的截图,里面容量的单位都是 kb 一直在看的elasticsearch的进程的一些参数设置的截图,使用的命令:jps -vm |grep elastic 从上面的gc的图,可以看出不少理论: 1,2个s区,但是一直有个s区的used是0.0,是空白的。 2,2个s区大小是一致的 3,上面截图中出现一次young gc(0.0换列的那个地方),YGC 次数由10703次变成10704次,加1,young gc之前,eden区都快满了538926.4 / 545344 = 98.8%了,gc之后,s1被完全回收,eden区的空间被回收大部分,s0区被安排了些新生的数据对象,old used 由529563.2变成了529706.2,增加了一点点,说明有部分对象被安排到了老年代去了。后面的gc time肯定不是某一次的gc时间,而是从启动到现在的总时间,从图中看到没有发生gc之前,这个值是一直不变的,gc之后,稍微长大了一丢丢。算一下,一次young gc的时间是0.011秒,full gc 没有在打印期间触发,后面的整个gc 时间增加也就0.01秒。启动2天的es的full gc的次数136,整个full gc的时间也就8秒多。启动之后整个程序的所有gc时间400多秒。 4,young gc 的次数比full gc的次数少的多,一个是1.1万次,一个是100多次。 (full难道不是整个堆内存吗?为啥有的人说full gc是对old区进行gc呢?我反对。所以,我上面写的就是对整个堆内存gc) 5,-gccapacity 与-gc基本相同,主要关注Java堆各区域使用到的最大最小空间 jstat -gccapacity 64363 1s 100 Java内存的差不多每个分区都有相应的配置来设置这个区域的最大值和最小值,在实际分配空间的时候,不够的时候会自动扩展,直到达到此区域的最大值,还无法满足程序在内存分配空间的时候,才会报OOM异常。想一下jvm里面几个分区的OOM情况。 在上面的实际图中,年轻代,老年代的最大最小设置的一样的,所以这2个分区的大小就是固定的,另外2个元空间和压缩类空间最小值是0,那大小会动态变化的就是后面这2个分区,以及young gc和full gc的次数了。截图中并没有发生young gc。 6,-gcutil 与-gc基本,主要关注已使用空间占此空间的百分比 jstat -gcutil 64363 1s 100 截图里面发生了一次young gc,2个s区一个被清空,eden区的使用率99.75变成9.6之后,一路往上涨,最终又触发下一次young gc old区百分比比较稳定,说明堆里面的对象基本都在这个eden区出生,在新生代中,大部分对象都干完事儿就被和谐了,内存使用正常,要是代码中有会造成内存溢出的代码,那么这个old区的百分比,每次young gc之后,就会涨,直到OOM,或者不OOM,但是卡在快满的情况下。 7,-gccause 与-gcutil一样,多2列输出导致上次gc的原因 jstat -gccause 64363 1s 100 还是差不多,eden区,使用百分比一路上升到百分百的时候,对象没地方分配空间了,就触发young gc,上次gc的原因,就是 Allocation Failure 分配空间失败。 垃圾回收还会有其它原因吗? 比如,我们通过代码显示调用System.gc(),是不是可以手动的告诉jvm gc一下,还有不少其它的方法,我也不知道。。。 8,-gcnew 统计新生代的gc情况 jstat -gcnew 64363 1s 100 这些新参数TT MTT DSS 估计和jvm的新生代的设计有关系了,暂时看不出门道来。 上图发生来young gc,时间大概0.003秒 9, -gcnewcapacity 类似 -gcnew,关系new区的各个最大和最新空间 jstat -gcnewcapacity 64363 1s 100 上面看到新生的最大最小设置一样,几个区的容量都是定值,不带变化的。 新生代大小 = s0 + s1 + eden = new区 上面截图中发生了gc的,但是gc跟new区的几个子分区的容量是不会有关系的。 10,-gcold 统计old区,堆里面老年代的gc情况 jstat -gcold 64363 1s 100 最终没被回收的对象都在堆的老年代里面,看老年代的已经使用的大小,再考虑考虑自己代码里面不回收的对象的大小,会不会把这个地方占满,会不会占这么大的空间。可以大致目测一下对象个数。推测这个区的占用是否合理,来判断代码是不是内存泄露了。不过,这个太难了,堆里面又不是只分你的对象,还有不少其它jar包自带的 11,-gcoldcapacity 统计old区的各个分区的容量最大最小情况 jstat -gcoldcapacity 64363 1s 100 好像也没啥,就是看看各个区的大小,这个截图里面old区的最大最小当前实际都是一个值。 12,-gcpermcapacity 被 -gcmetacapacity 替代,看元空间的gc情况 jstat -gcmetacapacity 64363 1s 100 他当时写那本书的时候,还在jdk1.6呢,在1.8之后jvm中内存分区有变化了,方法区变成了元空间。 当时说方法区的gc回收效果并不可观,没有堆的gc那么可观,一次gc回收 80%的空间。 估计一般gc都是主要看堆,看堆的 new 和old,重点都在old区。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |