0.结论
JDK1.8中JVM堆中新生代三部分比例不是8:1:1的问题来源于:
1.JDK1.8中的默认GC UseParallelGC 会自动开启 UseAdaptiveSizePolicy 「自适应大小策略」,会导致自动调整新生代各区域大小;
2.但使用 关闭命令:-XX:-UseAdaptiveSizePolicy 无法关闭该策略,原因未知;
3. 如需要看到8:1:1的默认比例方法如下:
- -XX:SurvivorRatio=8
- 使用CMS等默认关闭 AdaptiveSizePolicy 的GC算法
1.起因
最近研究虚拟机,在学习到运行时数据区中的java堆有这样的疑问
-XX:SurvivorRatio
在缺省的情况下表示新生代Eden区域和Survivor区域(From幸存区或To幸存区)的比例默认为8,即Eden区域与From区域与to区域的比例为8:1:1
但是实际测试并不是这样的
2.实际测试
本人环境:
java version “1.8.0_251”
Java™ SE Runtime Environment (build 1.8.0_251-b08)
Java HotSpot™ 64-Bit Server VM (build 25.251-b08, mixed mode)
2.1参数为 -Xms300m -Xmx300m 时,比例6:1:1
此时居然6:1:1!查询资料可知与「自适应大小策略」有关,在jdk1.8中,默认的GC为UseParallelGC,该垃圾回收器默认开启了AdaptiveSizePolicy(相关源码 arguments.cpp中的set_parallel_gc_flags 方法)
如果开启了这个参数,则每次 GC 后会重新计算 Eden、From 和 To 区的大小。计算依据是 GC 过程中统计的 GC 时间、吞吐量、内存占用量。
知道了原因,如何解决呢?
2.2 参数为-Xms300m -Xmx300m -XX:-UseAdaptiveSizePolicy 时,比例仍为6:1:1
开启:-XX:+UseAdaptiveSizePolicy
关闭:-XX:-UseAdaptiveSizePolicy
虽然我使用 jinfo 命令确认了显式地关闭了 UseAdaptiveSizePolicy ,但比例仍然对不上,这让我困惑
2.3参数为-Xms300m -Xmx300m -XX:SurvivorRatio=8 时,比例8:1:1!
使用 -XX:SurvivorRatio 指令后发现eden和survivor变成了熟悉缺省比例。
另外查询资料发现,来源:IBM Knowledge Center
避免故障
-XX:SurvivorRatio= option 与 Java 虚拟机参数 -XX:+UseAdaptiveSizePolicy 不相容。 因此请根据您的情况使用其中某一个值。
即 -XX:SurvivorRatio = option
和 -XX:+UseAdaptiveSizePolicy
最好别一起用,
另外在使用 -XX:SurvivorRatio
,最好关闭「自适应大小策略」 -XX:-UseAdaptiveSizePolicy
。(查询资料中发现有些人需要将前两个命令都设置才能看到8:1:1的效果,可能是JDK版本问题)
3.其它收获
- 为什么 CMS GC 默认关闭
UseAdaptiveSizePolicy
?
在arguments.cpp 类中的set_cms_and_parnew_gc_flags
方法,其调用了disable_adaptive_size_policy
方法将UseAdaptiveSizePolicy
设置成 false。
具体静态方法的代码