关于JVM参数-XX:SurvivorRatio的理解

关于JVM参数-XX:SurvivorRatio的理解

JVM参数中有一个比较重要的参数SurvivorRatio,它定义了新生代中Eden区域和Survivor区域(From幸存区或To幸存区)的比例,默认为8,也就是说Eden占新生代的8/10,From幸存区和To幸存区各占新生代的1/10

-XX:SurvivorRatio

这里举个例子,如果我们通过设置-Xmn60M来指定新生代分配的空间大小,那么Eden则会分配60M * 0.8 = 48M,Survivor一共分配60M * 0.2 = 12M的内存空间

下面我们通过实际命令行的演示来验证上面的结果

启动参数配置
-Xmn60M
-XX:SurvivorRatio=8
-XX:+PrintFlagsFinal
控制台输出
uintx NewSize         := 62914560    {product}
uintx MaxNewSize      := 62914560    {product}

注:这里只列举了部分重要的指标

可以看到新生代内存大小为62914560B=60M已经生效,因为Eden区和Survivor区的大小使用JVM参数无法在控制台中查到,所以我们借助Java VisualVM中的Visual GC插件来查看具体指标
关于JVM参数-XX:SurvivorRatio的理解_第1张图片
OK,指标验证已完成!

参数值分析

经过上面的测试我们已经大致理解了新生代内存分配的策略,其实到这一步还没有结束,我们还需要搞清楚下面几个问题:

  • Eden和Survivor比例有什么标准或要求吗?
  • 为什么要设置Eden和Survivor的大小比例?

假设1:Eden区域设置太大

新生成的对象会被分配在Eden区,Eden空间不足时会触发MinorGC。理想状态下,如果所有对象在这个阶段全部被回收,Eden区域被清空,不会出什么问题。如果GC后还存在一部分幸存的对象,则会被复制到To Survivor区域,此时因为Survivor区域空间太小无法容纳这些对象,结果大部分幸存对象只在进行一次或很少次的GC后就会被移动到老年代,也就是说从某种程度上来讲失去了MinorGC的初衷,这种情况是肯定不被允许的

假设2:Eden区域设置太小

接着分析,Eden区域设置太小,意味着其空间很快就会被占满,也就是说增加了新生代的GC次数,而频繁的GC会降低整体JVM性能

总结

一般情况下该参数使用默认值即可,除非你在JVM优化领域有着非常丰富的经验。总之,尽可能最小化"短暂对象"移动到老年代的数量,同时最小化年轻代GC的次数和持续时间,要找到适当的折衷方案,首先要了解应用程序中对象年龄的分布情况

你可能感兴趣的:(关于JVM参数-XX:SurvivorRatio的理解)