背景
最近系统总出现younggc次数过高的情况,时间点还不统一,取了GC频繁时的GC日志,用GCeasy分析一下。
GCEasy简介
gceasy 是一款非常不错的GClog分析工具,是在线的,可以免费分析,可以上传相关的gc日志进行在线分析:https://gceasy.io/gc-index.jsp#banner
GCEasy 实战分析
- GC内存情况分析:
这里是JVM内存的分配情况,说明年轻代已分配 2.41gb 峰值的时候分配 2.4gb
老年代 已分配 3.8gb 峰值 751.6mb,总的内存大小
2.关键性能指标
主要有吞吐率(正常业务执行的时间占比,其实粗略算的话,就是1- 减去GC的时间占比)、延迟时间(GC停顿时间) 组成,会展示出平均、最大延迟时间以及在GC日志期间,不同停顿时间的占比。
一般来讲,我们GC的调优的目的,就是提高吞吐率,降低GC的平均停顿时间(降低最大,减少次数)。
- GC交互视图
这个是这个时间段GC的全面的分析曲线图,分别为GC之后的堆、GC之前的堆,GC的时间、回收字节数、年轻代、老年代、分配与晋升对比、对象任期总结。
前两个不再展开,就是GC前后堆的大小。
我们看下GC Duration:GC的持续时间,这个比较有意思(选中局部可以放大),这张图里点其实涵盖了并行时候的gc时间和stop the world的时间,是总的gc时间。
GC回收的字节数目:
选中局部依然可以放大,并且一个点代表一次gc的回收字节的大小,可以看出10:22-10:24gc次数相当频繁,但是回收效率也低,后续会发现原因是这个时刻,年轻代分配空间极小。
年轻代大小:
分配的空间 和 gc 前后的大小,可以看出分配空间在22-23分很小,并且均GC前都沾满了,GC后都回收了。
年老代大小:
同上,说明了22-23的年轻代都分配给了年代,分配了将近3.8g, 但年老代的占用并不大,需要观察下原因。
分配与晋升情况
根据下图可知,晋升一直不是很高。
期望的幸存者区大小 与 实际的幸存者区大小:
这个其实跟我们配置的一个参数有关系 ::-XX:TargetSurvivorRatio (设定survivor区的目标使用率)
desired survivor size = (survivor区容量 * TargetSurvivorRatio)/100(其实就是survivor容量乘以这个targetSurvivorRatio的比值) 有兴趣的大家可以继续去看,这里笔者就不过多介绍了。
4.GC统计信息
这里不再一一说明:
上面三张图:回收的字节数 、GC的时间、GC的平均时间 ,可以看出没有fullgc(这个跟G1垃圾收集器的特性有关)。
下面的是GC的统计:总的GC次数、总的回收字节数、总的GC时间、gc平均时间。。。
5.GC停顿信息的统计
6.对象的统计信息
总共创建对象的大小、总共晋升的大小、两者的速率。
可以看出这个对象的创建速率还是蛮高的,需要优化。
7. 内存泄露、fullgc、长停顿
8.安全点持续时间:
这里的安全点其实指的是stop the world的时间点,这里的时间其实指的也是stop the world 的总时间。
9.GC 起因
10.对象任期总结
总结
上面是GCEasy总的分析报告了,从该报告,其实还是发现了一些问题的,比如内存分配的速率、内存分配的总的字节数很高,说明需要优化对象的创建数量或对象大小。
在特殊的时间点,发现年轻代突然变得很小,这个时间段会造成频繁younggc,需要仔细根据业务场景进一步分析,为何当时GC的年老代分配很大的内存。
希望本文对大家有所帮助,也希望有问题一起探讨。