1、jstat 使用
jstat -gc pid
1.SOC:这是From Survivor区大小
2.S1C:这是To Survivor区大小
3.SOU:From Survivor当前使用的内存大小
4.S1U:To Survivor当前使用的内存大小
5.EC:Eden区的大小
6.EU:Eden区当前使用的内存大小
7.OC:老年代大小
8.OU:老年代当前内存使用大小
9.MC:方法区(永久代,元数据区)大小
10.MU:方法区(永久代,元数据区)当前内存使用大小
11.CCSC:压缩类空间大小
12.CCSU:压缩类空间使用大小
13.YGC:系统运行到现在的young gc次数
14.YCGT:young gc的耗时
15.FGC:系统运行到现在的fullgc次数
16.FGCT:fullgc耗时
17.GCT:所有GC的总耗时
jstat -gc pid 1000 100
一秒钟执行一次,执行100下
jstat -gcutil 1000 100
和gc基本相同,输出主要关注已使用空间占总空间的百分比
其他的jstat 命令
推测相关数据
1、推测YGC触发频率和耗时
执行这个命令之后,第一秒先显示出来Eden区使用了200MB内存,第二秒显示出来的那行统计信息里,发信Eden区使用了205MB内存,第三秒显示出来的那行统计信息里,发现Eden区使用了209MB内存,以此类推。
根据自己系统的情况灵活多变的使用,比如你们系统负载很低,不一定每秒都有请求,那么可以把上面的1秒钟调整为1分钟,甚至10分钟,去看你们系统每隔1分钟或者10分钟大概增长多少对象。
多久触发一次Young GC就很容易推测出来了,因为系统高峰和日常时候的对象增长速率你都知道了,那么非常简单就可以推测出来高峰期多久发生一次Young GC,日常期多久发生一次Young GC。
比如你Eden区有800MB内存,那么发现高峰期每秒新增5MB对象,大概高峰期就是3分钟会触发一次Young GC。日常期每秒新增0.5MB对象,那么日常期大概需要半个小时才会触发一次Young GC。
比如系统运行24小时后共发生了260次Young GC,总耗时为20s。那么平均下来每次Young GC大概就耗时几十毫秒的时间。
2、推测每次YGC后有多少对象是存活和进入老年代
之前我们已经推算出来高峰期的时候多久发生一次Young GC,比如3分钟会有一次Young GC。
那么此时我们可以执行下述jstat命令:jstat -gc PID 180000 10。这就相当于是让他每隔三分钟执行一次统计,连续执行10次。
此时大家可以观察一下,每隔三分钟之后发生了一次Young GC,此时Eden、Survivor、老年代的对象变化。
正常来说,Eden区肯定会在几乎放满之后重新变得里面对象很少,比如800MB的空间就使用了几十MB。Survivor区肯定会放入一些存活对象,老年代可能会增长一些对象占用。所以这里的关键,就是观察老年代的对象增长速率。
存活对象太多,可能导致放入Survivor区域之后触发了动态年龄判定规则进入老年代,也可能是Survivor区域放不下了,所以大部分存活对象进入老年代。
最常见的就是这种情况。如果你的老年代每次在Young GC过后就新增几百KB,或者几MB的对象,这个还算情有可缘,但是如果老年代对象快速增长,那一定是不正常的。
3、FGC的触发事件和耗时
只要知道了老年代对象的增长速率,那么Full GC的触发时机就很清晰了,比如老年代总共有800MB的内存,每隔3分钟新增50MB对象,那么大概每小时就会触发一次Full GC。
然后可以看到jstat打印出来的系统运行起劲为止的Full GC次数以及总耗时,比如一共执行了10次Full GC,共耗时30s,每次Full GC大概就是需要耗费3s左右。