• jstat分析JVM的gc使用情况和查看full gc频率


    一、介绍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次数过多,则需根据压测业务结合代码分析定位。
  • 相关阅读:
    20200925--矩阵加法(奥赛一本通P93 6 多维数组)
    20200924--图像相似度(奥赛一本通P92 5多维数组)
    20200923--计算鞍点(奥赛一本通P91 4)
    20200922--计算矩阵边缘元素之和(奥赛一本通P91 3二维数组)
    20200921--同行列对角线的格(奥赛一本通P89 2 二维数组)
    磨人的.net core 3.1(二) DataReader的问题
    磨人的.net core 3.1(一) CORS的问题
    Vue SSR问题:返回的js打包文件为HTML文件
    axios与.net core API实现文件下载
    .Net Core API中基于System.Threading.Timer的定时任务
  • 原文地址:https://www.cnblogs.com/uestc2007/p/16309640.html
Copyright © 2020-2023  润新知