我们知道HotSpot VM 是基于分代垃圾收集机制gc的(G1也是一种特殊的分代机制,动态分代),那么在分代收集的过程中显然会存在一个问题那就是跨代引用。比如当我们进行young gc时,新生代中的对象是完全有可能被老年代所引用的。然而young gc的过程中我们并不会收集老年代中的对象(无论是否存活),当jvm从gc roots 出发trace的过程中如果出现老年代对象会直接中断这条trace路径,这个时候为了防止将新生代中存活的对象误判为死亡我们不得不将老年代中的对象当作gc roots的一部分。
既然这样为什么不直接不要中断老年代的trace路径呢? 是的,如果我们将所有的老年代对象都当作young gc的gc roots的话我们还不如不切断老年代的的trace路径来的效率高。但是在jvm的实际实现中,我们会在新生代上建立一个全局Remembered Set数据结构,这个结构把老年代分成数个小块,并标识出那一块会存在跨代引用。当发生young gc的时候只有包含跨代引用的小块才会被加入gc roots扫描。 显然这样做虽然多了一个维护Remembered Set的开销,但总的来说比之将老年代整体加入gc roots扫描肯定时间效率要高多了。那么它就一定保证比不中断老年代trace链快吗?从跨代引用假说上来说,是的!
跨代引用假说:跨代引用相对于同代引用来说只占极少数。