arthas 排查内存溢出_线上full gc分析与排查指南

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。

老年代(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里面)

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值