jvm问题实录2-来自凌晨的线上堆内存使用率告警

时间:2024-04-07 19:30:36

线上现象(来自凌晨的问候)

  1. 凌晨3点线上项目在监控平台上开始报警(jvm堆内存占用报警超过80%,持续报警)
    jvm问题实录2-来自凌晨的线上堆内存使用率告警
  2. 观察具体的监控图标(线程数平稳) 时间:2019-06-13 首先要看方法调用量有没有大量提升,通过排查没有
    jvm问题实录2-来自凌晨的线上堆内存使用率告警
    jvm问题实录2-来自凌晨的线上堆内存使用率告警
    jvm问题实录2-来自凌晨的线上堆内存使用率告警
    jvm问题实录2-来自凌晨的线上堆内存使用率告警

逻辑分析(定位问题大致方向)

  1. 通过当天监控数据分析,堆内存持续上升,在凌晨3点左右触及报警配置水位1800/2048 >80%,导致报警
  2. 非堆、cpu、线程数稳定
  3. 系统Young GC频繁,Full GC暂时没有

当前推论 :系统YGC已经不能回收太多堆内存,而FGC还没有执行,可能是因为老年代在持续增长
需要查看当前机器自启动以来的历史数据参考(因为当前线上一次查询范围最大1天),
2019-06-10 ->11号 数据,和12号的比对,可以看出堆内存水位在缓慢上升,最终再13号凌晨出发报警。
jvm问题实录2-来自凌晨的线上堆内存使用率告警
jvm问题实录2-来自凌晨的线上堆内存使用率告警
jvm问题实录2-来自凌晨的线上堆内存使用率告警
接着推论 :

  1. 老年代持续上升,按照CMS的默认92%处理机制,如果是正常内存使用,我们不用管报警,达到高水位自动FGC,堆内存恢复低位,
  2. 但是如果是因为内存泄露引起的问题,那么按照目前速率可能会在2-3天后(也可能是618促销期间)出现内存溢出宕机。
    jvm问题实录2-来自凌晨的线上堆内存使用率告警

线上验证

验证之前要小心,最好先把机器从集群摘除,因为FullGC会影响机器性能
接下来我们要验证一下是正常的使用还是内存泄露,采用手动触发一次FGC,执行histo命令
jvm问题实录2-来自凌晨的线上堆内存使用率告警jvm问题实录2-来自凌晨的线上堆内存使用率告警
结论: 从监控可以看出,触发了FGC后,堆内存直接降到低水位,因此我们可以理解为是正常的内存增长,
后续的工作 : 1. 从dump及代码层面分析为什么老年代持续增长, 2. 更改一下监控报警配置 等优化

我们也可以通过监控看到刚才执行的FGC对方法性能的影响,
jvm问题实录2-来自凌晨的线上堆内存使用率告警
jvm问题实录2-来自凌晨的线上堆内存使用率告警

后记

讲个细节(为什么凌晨会持续报警)?

  1. 报警规则
    jvm问题实录2-来自凌晨的线上堆内存使用率告警
  2. 长期运行后正好赶上了凌晨…
  3. 凌晨调用量小,YGC间隔大,内存在间隔期长时间高水位jvm问题实录2-来自凌晨的线上堆内存使用率告警jvm问题实录2-来自凌晨的线上堆内存使用率告警
    troube shooting 三要素: 锻炼自己的逻辑思维、锻炼自己的技术能力、多看多查