频繁发生fullgc的原因和定位思路
频繁full gc会导致
1. 机器 cpu 负载过高
2. 频繁 full gc 告警
3. 系统无法请求处理或者过慢, 接口无关 全面性的
出现以上异常的时候,要第一时间反应过来可能是 full gc的问题
频繁full gc的常见原因
full gc 触发条件是 老年代空间不足, 所以追因的方向就是导致 老年代空间不足的原因:
大量对象频繁进入老年代 + 老年代空间释放不掉
- 系统并发高、执行耗时过长,或者数据量过大,导致 young gc频繁,且gc后存活对象太多,但是survivor 区存放不下(太小 或 动态年龄判断) 导致对象快速进入老年代 老年代迅速堆满
- 发程序一次性加载过多对象到内存 (大对象),导致频繁有大对象进入老年代 造成full gc
- 存在内存溢出的情况,老年代驻留了大量释放不掉的对象, 只要有一点点对象进入老年代 就达到 full gc的水位了
- 元数据区加载了太多类 ,满了 也会发生 full gc
- 堆外内存 direct buffer memory 使用不当导致
- 也许, 你看到老年代内存不高 重启也没用 还在频繁发生full gc, 那么可能有人作妖,在代码里搞执行了 System.gc();
定位思路
如果有监控,那么通过图形能比较直观、快速的了解gc情况;
如果没有监控,那么只能看gc日志或jstat来分析 这是基本技能 一定要熟练
- 观察年轻代 gc的情况,多久执行一次、每次gc后存活对象有多少 survivor区多大
存活对象比较多 超过survivor区大小或触发动态年龄判断 => 调整内存分配比例 - 观察老年代的内存情况 水位情况,多久执行一次、执行耗时多少、回收掉多少内存
如果在持续的上涨,而且full gc后回收效果不好,那么很有可能是内存溢出了 => dump 排查具体是什么玩意 - 如果年轻代和老年代的内存都比较低,而且频率低 那么又可能是元数据区加载太多东西了
- 其实如果是自己负责的系统,可能要看是不是发版改了什么配置、代码
本文来自博客园,作者:mushishi,转载请注明原文链接:https://www.cnblogs.com/mushishi/p/14553105.html