JVM中新生代为什么要有两个Survivor(form,to)?

今天看《深入研究java虚拟机原理》,上面提到复制算法的时候说一般将堆内存分为一块较大的Eden和两块较小的Survivor,每次只使用Eden和其中…
关注者
65
被浏览
76,146
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

建议看一下周志明的《深入理解Java虚拟机》一书,讲的还是比较好的,有个别瑕疵,可以参考R大对此书的读出笔记,豆瓣可见。

新生代用的是复制算法,关于复制算法就不多说了,HotSpot中年轻代使用的是改良的复制算法,年轻代分为一个Eden区和两个Survivor区,而年轻代可使用的大小为Eden区+一个Survivor区,剩余的一个Survivor区用来GC是来回复制使用,因为年轻代的效率比较高,Eden区大多数的对象会被回收掉,所以Survivor区的大小不是很大,默认大小比例为Eden:Survivor0:Survivor1=8:1:1,可通过参数调整比例。

至于为什么有两个Survivor区,应该是为了提高GC的效率。

除特殊情况下,在一次YGC中,Eden区的对象要不被回收,要不进入Survivor区,而在Survivor区小大够用的情况下,已在Survivor区的对象并不会马上进入年老代,而是仍然需要待在Survivor区,直到达到一定的年龄,而这个年龄就是YGC的次数,当然这个年龄阀值是可以人工设置的。

如果只有一个Survivor区,YGC时Eden区的对象可以进入Survivor区,那Survivor区的去的哪里呢?如果是进入年老代,那么其实本次YGC进入Survivor区的对象必须在下次YGC时进入年老代或被回收,这样YGC的效率就不高了。

如果我们规定只有经历了15次(默认,可通过参数调整)YGC还活下来的对象可以进入年老代,那么大大提高了YGC的效率,使得只有少数活下来的对象进入年老代,保证年老代的增长速率的缓慢,从而降低年老代GC的次数,保证整个JVM的工作效率。

所以正是因为存在两个Survivor区,使得Survivor区的对象也可以来回的复制,而不是马上进入年老代,直到到达一定的年龄才进入老年代,尽可能的保证进入年老代的是真的够资格的。

第一次回答,比较啰嗦,有问题还请大大们斧正。