java jdk1.8 AdaptiveSizePolicy可能导致频繁垃圾回收及延迟响应

java虚拟机在可用内存空间减少时,会增加垃圾回收的次数,而垃圾回收是需要消耗时间的,会出现短暂的停顿(STW,stop the world)现象,如果频繁的进行垃圾回收,特别是老年代的垃圾回收,则会影响到请求的响应时间。

1. 现象

以下是一个项目中使用jdk8默认参数运行时,jmap -heap 内存使用情况图。可以看到 Survivor 区使用占比 71%,在比较高的水平。

仔细观察这张图,其中包含几个重要信息:

  1. From 和 To 区都比较小,只有 2M。容量比较小,才显得占比高。
  2. Old 区的占比和使用量都比较高。

此外,还可以看到 Eden、From、To 之间的比例不是默认的 8:1:1。于是,立马就想到 AdaptiveSizePolicy。

2. 自适应大小策略AdaptiveSizePolicy

AdaptiveSizePolicy(自适应大小策略) 是 JVM GC Ergonomics(自适应调节策略) 的一部分。

如果开启 AdaptiveSizePolicy,则每次 GC 后会重新计算 Eden、From 和 To 区的大小,计算依据是 GC 过程中统计的 GC 时间、吞吐量、内存占用量

JDK 1.8 默认使用 UseParallelGC 垃圾回收器,该垃圾回收器默认启动了 AdaptiveSizePolicy。

AdaptiveSizePolicy 有三个目标:

  1. Pause goal:应用达到预期的 GC 暂停时间。
  2. Throughput goal:应用达到预期的吞吐量,即应用正常运行时间 / (正常运行时间 + GC 耗时)。
  3. Minimum footprint:尽可能小的内存占用量。

AdaptiveSizePolicy 为了达到三个预期目标,涉及以下操作:

  1. 如果 GC 停顿时间超过了预期值,会减小内存大小。理论上,减小内存,可以减少垃圾标记等操作的耗时,以此达到预期停顿时间。
  2. 如果应用吞吐量小于预期,会增加内存大小。理论上,增大内存,可以降低 GC 的频率,以此达到预期吞吐量。
  3. 如果应用达到了前两个目标,则尝试减小内存,以减少内存消耗。

AdaptiveSizePolicy 看上去很智能,但有时它也很调皮,会引发 GC 问题

通过jstat -gcutil命令查看垃圾回收情况,如果出现了频繁的垃圾回收(比如每几分钟就存在一次FGC),而且垃圾回收时间长(比如FGC超过200ms),则有比较对默认策略进行调整。

平均停顿时间超过200ms,对于高 QPS 应用的影响是明显的。

3. 解决方案

3.1 显示设置内存分配比例

保持使用 UseParallelGC,显式设置 -XX:SurvivorRatio=8

配置参数进行测试:

看到默认配置下,三者之间的比例不是 8:1:1。

可以看到,加上参数 -Xmn100m -XX:SurvivorRatio=8 参数后,固定了 Eden 和 Survivor 之间的比例。 

这里的参数根据具体环境进行调整。

3.2 使用 CMS 垃圾回收器

使用 CMS 垃圾回收器。CMS 默认关闭 AdaptiveSizePolicy。

配置参数 -XX:+UseConcMarkSweepGC,通过 jinfo 命令查看,可以看到 CMS 默认减去/不使用 AdaptiveSizePolicy。

可以看出,Eden 和 Survivor 之间的比例被固定,To 区没有被缩小。老年代的使用量和使用率也都很正常。

4. 问题小结

  1. 使用 JDK 1.8,默认垃圾回收器是Parallel Scavenge,并且默认开启 AdaptiveSizePolicy;
  2. AdaptiveSizePolicy 动态调整 Eden、Survivor 区的大小,存在将 Survivor 区调小的可能。当 Survivor 区被调小后,部分 YGC 后存活的对象直接进入老年代。老年代占用量逐渐上升从而触发 FGC,导致较长时间的 STW;
  3. 建议使用 CMS 垃圾回收器,默认关闭 AdaptiveSizePolicy;
  4. 建议在 JVM 参数中加上 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution,让 GC log 更加详细,方便定位问题;
  5. 在大内存(比如8GB及以上)和高QPS的情况下,确保快速响应时间,可以考虑使用G1垃圾回收器进行垃圾回收,G1垃圾回收期可以每次收集部分垃圾来满足小的停顿时间要求

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值