JVM是如何解决跨代引用的?

跨代引用问题

假如要现在进行一次只局限于新生代区域内的收集(Minor gc),但新生代的对象1在老年代中被引用,为了找出该区域(新生代)中所有的存活对象,不得不在固定的gc roots之外,在额外遍历整个老年代中所有对象来确保可达性分析结果的正确性。
遍历整个老年代所有对象的方案虽然可行,但是会给内存回收带来很大的性能负担。

实时上并不是只有新生代、老年代才有跨代引用的问题,所有涉及部分区域手机行为的垃圾收集器,典型的如G1、ZGC收集器,都会面临同样的问题。

如何解决跨代引用

先说结论,JVM是使用 写屏障 + 卡表 解决的。

  • 首先,跨代引用是少数的,例如:某个新生代对象存在跨代引用,由于老年代对象难以消亡,就会导致新生代对象在收集时同样得已存活,进而在年龄增长之后晋升到老年代中了。
  • 所以就不用为了少量的跨代引用扫描整个老年代,只需要在新生代建立一个全局的数据结构(该结构被称为 记忆集,Rember Set),标识出老年代的哪一块内存存在跨代引用,此后发生minor gc时,只有包含了跨代引用的小块内存里的对象才会被加入gc root进行扫描。
  • 个人理解,card table是用来划分老年代的,即把老年代划分多个大小相等的连续区域,而Rember set中记录了卡表的位置。

记忆集(Remembered Set)

一种记录 从非收集区域(如老年代) 指向 收集区域(如年轻代)的指针集合的抽象数据结构&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值