频繁发生fullgc的原因和定位思路

频繁full gc会导致

1. 机器 cpu 负载过高
2. 频繁 full gc 告警
3. 系统无法请求处理或者过慢, 接口无关  全面性的

出现以上异常的时候,要第一时间反应过来可能是 full gc的问题

频繁full gc的常见原因

full gc 触发条件是 老年代空间不足, 所以追因的方向就是导致 老年代空间不足的原因:
大量对象频繁进入老年代 + 老年代空间释放不掉

  1. 系统并发高、执行耗时过长,或者数据量过大,导致 young gc频繁,且gc后存活对象太多,但是survivor 区存放不下(太小 或 动态年龄判断) 导致对象快速进入老年代 老年代迅速堆满
  2. 发程序一次性加载过多对象到内存 (大对象),导致频繁有大对象进入老年代 造成full gc
  3. 存在内存溢出的情况,老年代驻留了大量释放不掉的对象, 只要有一点点对象进入老年代 就达到 full gc的水位了
  4. 元数据区加载了太多类 ,满了 也会发生 full gc
  5. 堆外内存 direct buffer memory 使用不当导致
  6. 也许, 你看到老年代内存不高 重启也没用 还在频繁发生full gc, 那么可能有人作妖,在代码里搞执行了 System.gc();

定位思路

如果有监控,那么通过图形能比较直观、快速的了解gc情况;
如果没有监控,那么只能看gc日志或jstat来分析 这是基本技能 一定要熟练

  1. 观察年轻代 gc的情况,多久执行一次、每次gc后存活对象有多少 survivor区多大
    存活对象比较多 超过survivor区大小或触发动态年龄判断 => 调整内存分配比例
  2. 观察老年代的内存情况 水位情况,多久执行一次、执行耗时多少、回收掉多少内存
    如果在持续的上涨,而且full gc后回收效果不好,那么很有可能是内存溢出了 => dump 排查具体是什么玩意
  3. 如果年轻代和老年代的内存都比较低,而且频率低 那么又可能是元数据区加载太多东西了
  4. 其实如果是自己负责的系统,可能要看是不是发版改了什么配置、代码
posted @ 2021-03-18 01:15  mushishi  阅读(7189)  评论(0编辑  收藏  举报