为什么设置了SurvivorRatio=8,但是实际Eden与Survivor不是8:1:1

JDK 环境

1

JVM 参数

-Xms1G -Xmx1G -XX:SurvivorRatio=8

问题描述

但是出现的情况
当 -XX:SurvivorRatio=8 时,Eden 与 Survivor 的比例却不是 8:1:1

2

如上图:
新生代:341 MB;老年代:683 MB ;比例正常 1:2;
新生代内:
Eden: 293.5 MB;From:24MB;To:23.5MB;
比例不正常:Eden 区接近为 86%,而 Survivor 分别为 7%;
比例不是 Eden:From Survivor:To Survivor = 8:1:1

诡异的是:我将 -XX:SurvivorRatio=6 ,调整为 6 时,如下图:

3
新生代内:
Eden: 274MB;From:34 MB;To:33 MB:
比例为 Eden:From Survivor:To Survivor = 8:1:1

请问有大佬们经历过这种情况吗?

是有额外的东西影响到了这个参数吗?实在费解。

问题解决

问题的原因在于 AdaptiveSizePolicy(自适应大小策略),如果开启了这个参数,则每次 GC 后会重新计算 Eden、From 和 To 区的大小。计算依据是 GC 过程中统计的 GC 时间、吞吐量、内存占用量。

开启参数:-XX:+UseAdaptiveSizePolicy

但是我上面并未设置啊,这是什么原因呢?

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

结果验证

JVM 参数

Xms1G -Xmx1G

Eden : From : To = 8.5 : 0.7 : 0.7
4

仅加上参数 -XX:SurvivorRatio=8
Eden : From : To = 8.5 : 0.7 : 0.7
5

仅加上 -XX:-UseAdaptiveSizePolicy
Eden : From : To = 7.5 : 1.2 : 1.2
6

加上 -XX:-UseAdaptiveSizePolicy -XX:SurvivorRatio=8
Eden : From : To = 8 : 1 : 1
7

结论

如果使用使用 UseParallelGC 垃圾回收器,默认是开启 AdaptiveSizePolicy 参数的。
所以我们需要设置:-XX:-UseAdaptiveSizePolicy -XX:SurvivorRatio=8
才会达到真正的 Eden : From : To = 8 : 1 : 1

封面图拍摄于回家途中

乘坐轮渡,渡过长江,2020/01/21 骑摩托车渡江的人。

骑摩托归家的人

写在最后

如果觉得我的文章对你有帮助,可以关注一下我的微信公众号支持一下,万分感谢!

qrcode_for_gh_1b8f906d09f4_344