美文网首页技术分享
线上full gc分析与排查指南

线上full gc分析与排查指南

作者: 他是人间惆怅客 | 来源:发表于2019-04-17 19:39 被阅读113次

1.首先分析一下Full GC触发的几个条件:
1).调用System.gc时,系统建议执行Full GC,但是不必然执行
2). Perm空间不足;
3). CMS GC时出现晋升失败和concurrent mode failure(concurrent mode failure发生的原因一般是CMS正在进行,但是由于老年代空间不足,需要尽快回收老年代里面的不再被使用的对象,这时停止所有的线程,同时终止CMS,直接进行Serial Old GC);
4). 统计得到的Young GC晋升到老年代的平均大小大于老年代的剩余空间;
5). 主动触发Full GC(执行jmap -histo:live [pid])来避免碎片问题。

2.目前主流的HotSpot VM的垃圾回收都采用“分代回收”的算法,主要分为:新生代、老年代和持久代.
1)新生代(Young Generation):新建的对象会优先在新生代里面分配,而且新生代里面的对象一般生命周期都是比较短的。新生代的垃圾回收被称为Minor GC,经过Minor GC后只有少量对象存活,所以一般选用Copy算法,代价也比较小。

新生代内又分三个区:Eden区,两个Survivor区(From Survivor和To Survivor ),大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到两个Survivor区(中的一个)。当这个Survivor区满时,此区的存活且不满足“晋升”条件的对象将被复制到另外一个Survivor区。对象每经历一次Minor GC,年龄加1,达到“晋升年龄阈值”后,被放到老年代,这个过程也称为“晋升”。显然,“晋升年龄阈值”的大小直接影响着对象在新生代中的停留时间,在Serial和ParNew GC两种回收器中,“晋升年龄阈值”通过参数MaxTenuringThreshold设定,默认值为15。

  1. 老年代(Old Generation):在新生代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代,该区域中对象存活率高。老年代的垃圾回收(又称Major GC)通常使用“标记-清理”或“标记-整理”算法。整堆包括新生代和老年代的垃圾回收称为Full GC(HotSpot VM里,除了CMS之外,其它能收集老年代的GC都会同时收集整个GC堆,包括新生代)。

3)永久代(Perm Generation):主要存放元数据,例如Class、Method的元信息,与垃圾回收要回收的Java对象关系不大。相对于新生代和年老代来说,该区域的划分对垃圾回收影响比较小。

一般我们先上遇到Full GC的问题,首先不要急于去修改jvm参数去调优,因为JVM调优化不是必须的,一定要深入理解之后才去着手去做优化,其实绝大部分你排查下来以后发现是代码的问题.关于这部分,我总结了一些常用的问题.


JVM性能优化.jpg

3.当JVM发生Full GC的时候,会引发STOP THE WORLD现象,Full GC的代价是非常高的远比Minor GC花费的时间长,除了垃圾回收器这些守护线程以外,当前所有的用户线程会被挂起,所以这个时候的外部请求不会被处理,对于并发要求比较高的应用很害怕遇到这种情况,一般我们会调整负载均衡算法针对这种情况.

4.Full GC排查指南:
1)首先查看Full GC花费的时间,比如2秒或以上,这种一般都需要尽快进行调优了.
2)堆dump来分析验证内存溢出的原因.
堆dump是把内存情况按一定格式输出到文件,可用于检查Java 内存中的对象和数据情况。可使用JDK中内置的jmap命令创建堆dump文件。创建文件过程中,Java进程会中断,因此不要在正常运行时系统上做此操作。
3)例如用内存分析工具JVisualVM分析内存分配情况
4)一般我们的应用启动脚本里面会打印GC的日志,并且会提前设定阈值,在80%的可能就就会触发Gc了.
5)正常情况下,我们会优先看下云服务器的CPU、内存、磁盘等的状况,用下top命令.
6)借助arthas强大的工具分析
dashboard观察一下HTTP请求的qps, rt, 错误数, 线程池信息等等
thread -n 3查看当前最忙的前N个线程并打印堆栈
jvm查看当前jvm信息
用trace命令分析方法内部调用路径,并输出方法路径上的每个节点上耗时
7)通常CMS GC比Parallel GC要好,因为CMS GC的执行中并不会伴随内存压缩,因此GC速度会更快一些
8)如果调整好参数后,需要做性能测试,然后连续观察几天

5.关于jvm调优的一些小tips:
1)把Xms和Xmx设置为相同,这样可以减少GC后重新分配带来的性能开销
2)把MaxPermSize和MinPermSize设置成一样(JDK8开始,没有了Perm,代替为元空间。元空间是直接存在内存中,不在JVM里面)

相关文章

网友评论

    本文标题:线上full gc分析与排查指南

    本文链接:https://www.haomeiwen.com/subject/mdrpbqtx.html