一、介绍jstat

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:

jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]

1、命令格式

jstat命令命令格式: jstat [Options] vmid [interval] [count] 参数说明:

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

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

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

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

2、示例

通常运行命令如下:

  • 直接使用ps -ef | grep java查看java进程

  • jstat -gc 24076 5000

  • 即会每5秒一次显示进程号为24076的java进成的GC情况,

  • 如下表示分析进程id为24076的gc情况,每隔1000ms打印一次记录,打印10次停止,每3行后打印指标头部

  • jstat -gc -h3 24076 1000 10

二、示例

1 、垃圾回收统计jstat -gc pid

其对应的指标含义如下:

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

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

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

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

  • EC 年轻代中Eden(伊甸园)的容量 (字节)

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

  • OC Old代的容量 (字节)

  • OU Old代目前已使用空间 (字节)

  • MC 方法区大小

  • MU 方法区目前已使用空间 (字节)

  • CCSC 压缩类空间大小

  • CCSU 压缩类空间已使用大小

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

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

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

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

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

2、类加载统计jstat -class pid

  • Loaded:加载class的数量

  • Bytes:所占用空间大小

  • Unloaded:未加载数量

  • Bytes:未加载占用空间

  • Time:时间

3、编译统计jstat -compiler pid

  • Compiled:编译数量。

  • Failed:失败数量

  • Invalid:不可用数量

  • Time:时间

  • FailedType:失败类型

  • FailedMethod:失败的方法

4、JVM编译方法统计jstat -printcompilation pid

  • Compiled:最近编译方法的数量

  • Size:最近编译方法的字节码数量

  • Type:最近编译方法的编译类型。

  • Method:方法名标识。

5、堆内存统计jstat -gccapacity pid

 

  • NGCMN:新生代最小容量

  • NGCMX:新生代最大容量

  • NGC:当前新生代容量

  • S0C:第一个幸存区大小

  • S1C:第二个幸存区的大小

  • EC:伊甸园区的大小

  • OGCMN:老年代最小容量

  • OGCMX:老年代最大容量

  • OGC:当前老年代大小

  • OC:当前老年代大小

  • MCMN:最小元数据容量

  • MCMX:最大元数据容量

  • MC:当前元数据空间大小

  • CCSMN:最小压缩类空间大小

  • CCSMX:最大压缩类空间大小

  • CCSC:当前压缩类空间大小

  • YGC:年轻代gc次数

  • FGC:老年代GC次数

6、 新生代垃圾回收统计jstat -gcnew pid

 

  • S0C:第一个幸存区大小

  • S1C:第二个幸存区的大小

  • S0U:第一个幸存区的使用大小

  • S1U:第二个幸存区的使用大小

  • TT:对象在新生代存活的次数

  • MTT:对象在新生代存活的最大次数

  • DSS:期望的幸存区大小

  • EC:伊甸园区的大小

  • EU:伊甸园区的使用大小

  • YGC:年轻代垃圾回收次数

  • YGCT:年轻代垃圾回收消耗时间

7、 新生代内存统计jstat -gcnewcapacity pid

 

  • NGCMN:新生代最小容量

  • NGCMX:新生代最大容量

  • NGC:当前新生代容量

  • S0CMX:最大幸存1区大小

  • S0C:当前幸存1区大小

  • S1CMX:最大幸存2区大小

  • S1C:当前幸存2区大小

  • ECMX:最大伊甸园区大小

  • EC:当前伊甸园区大小

  • YGC:年轻代垃圾回收次数

  • FGC:老年代回收次数

8、老年代垃圾回收统计jstat -gcold pid

 

  • MC:方法区大小

  • MU:方法区使用大小

  • CCSC:压缩类空间大小

  • CCSU:压缩类空间使用大小

  • OC:老年代大小

  • OU:老年代使用大小

  • YGC:年轻代垃圾回收次数

  • FGC:老年代垃圾回收次数

  • FGCT:老年代垃圾回收消耗时间

  • GCT:垃圾回收消耗总时间

9、老年代内存统计jstat -gcoldcapacity pid

 

  • OGCMN:老年代最小容量

  • OGCMX:老年代最大容量

  • OGC:当前老年代大小

  • OC:老年代大小

  • YGC:年轻代垃圾回收次数

  • FGC:老年代垃圾回收次数

  • FGCT:老年代垃圾回收消耗时间

  • GCT:垃圾回收消耗总时间

10、元数据空间统计(持久代)jstat -gcmetacapacity pid

 

  • MCMN:最小元数据容量

  • MCMX:最大元数据容量

  • MC:当前元数据空间大小

  • CCSMN:最小压缩类空间大小

  • CCSMX:最大压缩类空间大小

  • CCSC:当前压缩类空间大小

  • YGC:年轻代垃圾回收次数

  • FGC:老年代垃圾回收次数

  • FGCT:老年代垃圾回收消耗时间

  • GCT:垃圾回收消耗总时间

11、查看full gc频率

ps -eo pid,tty,user,comm,lstart,etime | grep pid

三、总结垃圾回收统计(重点)

1、jstat命令用法: jstat -gcutil PID 1000

  • 找到PID:ps -ef |grep进程名

  • jstat -gcutil PID 1000 表示每隔1s执行一次

  • 输出结果:

  • S0:幸存1区当前使用比例

  • S1:幸存2区当前使用比例

  • E:伊甸园区使用比例

  • O:老年代使用比例

  • M:元数据区使用比例

  • CCS:压缩使用比例

  • YGC:年轻代垃圾回收次数

  • YGCT:年轻代垃圾回收消耗时间

  • FGC:老年代垃圾回收次数

  • FGCT:老年代垃圾回收消耗时间

  • GCT:垃圾回收消耗总时间

2、jstat分析JVM套路

1)jvm体系结构图

JVM内存结构分为了 年轻代(Young) 、年老代(Old)、元空间(Perm) 年轻代:复制算法

所有新生成的对象首先都是放在年轻代的,年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象

2)JVM 中 对象从创建到回收过程理解(结合上图理解)

a: YoungGC过程理解 新生代内存按照8:1:1的比例分为一个eden区和两个survivor(survivor0,survivor1)区。一个Eden区,两个 Survivor区。新new出来的对象会存储在 Eden(伊甸园)中,当这区域满了之后JVM会进行一次垃圾回收,在回收时把有用的对象存储在S1区,没用的就销毁此对象的内存空间,这过程即第一次YoungGC,如果S1区空间也满了后,同理会将有用的对象会放到S2区中,并释放S1空间,以上反复的回收即为YoungGC。

b: FullGC过程理解 年轻代空间满了之后,会将满足一定活跃度的对象放到Old区中(对象活跃度:每个对象满足JVM默认count=15之后就判断是活跃对象,每次YoungGC后会将存活对象生命中+1,直到=15就转到Old区,这个次数可以通过:-XX:MaxTenuringThreshold来配置), 由于Full GC需要对整个堆进行回收,导致应用访问变慢,因此应该尽可能减少Full GC的次数。

3、JVM内存回收如何判定回收不彻底?可能导致内存泄漏或溢出

如果 S0 、S1、 伊甸园区 这三个空间都有值的时候说明可能存在问题。

因为正常情况下是每次GC后,S0区、S1区中的空间总有一个是会被完全清空(根据GC垃圾回收算法),

因此S0 S1一直存在被占用时则回收不彻底,导致内存泄漏现象,随之时间拉长,甚至出现内存溢出(OOM)现象。

4、总结

  • 年轻代:复制算法

所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象

  • 年老代:标记-清除或标记-整理算法

在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象

  • 在压力测试过程中发现Eden区内存增加过快,根据压测VU和业务判断是否合理,从而判断YoungGC频率是否正常。

  • FullGC频率一般在半小时一次较为正常,具体根据真实业务判断,那么在压力测试过程中,监控到FullGC次数过多,则需根据压测业务结合代码分析定位。

本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。