老年代持续增长,无法触发 mixed gc 的解决方案

背景

封禁数据推送的需求上线后, 内存占用时不时达到 95% 以上, 且继续增长。
在这里插入图片描述

排查过程

  1. 在封禁数据推送的需求上线后,因其需要缓存 300-400w 数据, 所以需要的内存很大, 堆内存由 1g → 4g , 此时应用部署后, 内存占用会持续增长到 95% 左右, 然后缓慢波动, 持续两天未报警。
  2. 内存在 95 % 缓慢波动, 在凌晨到达阈值, 收到报警后, 临时措施重启服务。 在第二天错误的认为「堆内存不够」, 并多次提高堆内存 3g → 8g , 此时内存增长速率明显要比 3g 时要低
  3. 查看 jvm 相关监控, 锁定在老年代不断增长, 且无 gc 回收老年代的迹象, 查阅资料, 可能与 jvm 参数 XX:InitiatingHeapOccupancyPercent 有关,参数含义「默认值45,超过这个值,开始触发全局标记,进而触发mixed gc,注意这个值表示的是:老年区已使用空间/整个堆空间。计算可得 老年代需要占用空间为 8g * 0.45 = 3.6g 才能触发 mixed gc , 回收部分老年代空间, 从 jvm 监控可以看出, 老年代空间从未达到 3.6 g , 所以一直无法回收老年代, 导致老年代占用一路上涨。
  4. 调整措施, 将 XX:InitiatingHeapOccupancyPercent 设置为 20 , 堆内存调整为 7g , 老年代占用空间为 1.4 g 时, 即可触发 mixed gc。上线后可以看到, 内存占用指标稳定在 88% 左右, 但相应的 mixed gc 较为频繁, gc 耗时尖刺较多, 但从业务指标上看并无影响, 可以接受

Young GC:选定所有年轻代里的Region。G1是通过调整年轻代大小,控制年轻代Region数量来控制YGC的开销。

Mixed GC:选定所有年轻代里的Region,外加根据global concurrent marking统计得出收集收益高的部分老年代Region,在用户指定的停顿时间目标范围内尽可能选择收益高的老年代Region回收,G1就是通过控制回收老年代Region数量来控制Mixed GC的开销的。

FullGC:Serial Old GC

在这里插入图片描述

在这里插入图片描述

锁定在老年代不断增长
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

上线后

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

疑问

1.为什么没有触发 full gc ?

触发 full gc 需要老年代空间不足, 在本场景中, 因为堆内存设置过大, 导致老年代空间始终有很多空余, 导致一直未触发。

2.从 jvm 监控中看, 老年代的 committed 会不断增加, 这是为什么?

G1 本身的机制, 年轻代和老年代的空间是动态的, 当老年代占用空间过多时, 会将部分不用的年轻代空间合并, g1_eden_space 在那段时间里时不断下降的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值