理解G1 Remember Set(RSet)

Overview

G1的每个region都有一个Remember Set(Rset)
这个数据结构,用来保存别的region的对象对我这个region的对象的引用,通过Remember Set我们可以找到哪些对象引用了当前region的对象

参考这个文章

由于对我当前region对象的引用可能很多,也可能很少,G1会根据数量的变化来改变数据结构以达到节省空间的目的

第1种,哈希表

key是region的index,value是card数组。
card数组是个啥?

第2种,细粒度的PerRegionTable

这是一个Heap位图,每一位对应一个card
card又是个啥?

第3中,粗粒度位图

每一位代表对应的分区有引用到当前region,具体的对象还得在对应的分区里找

看代码吧那就

看的是jdk12源码

先看定义了哪些结构

src/hotspot/share/gc/g1/heapRegionRemSet.hpp

头部注释,介绍了Remember set

// Remembered set for a heap region.  Represent a set of "cards" that
// contain pointers into the owner heap region.  Cards are defined somewhat
// abstractly, in terms of what the "BlockOffsetTable" in use can parse.

就是一个set,记录了哪些card包含了指向我们当前region的指针。这个card是抽象的,BlockOffsetTable可以解析这个玩意儿?

再来一大段注释

// The "_coarse_map" is a bitmap with one bit for each region, where set
// bits indicate that the corresponding region may contain some pointer
// into the owning region.

// The "_fine_grain_entries" array is an open hash table of PerRegionTables
// (PRTs), indicating regions for which we're keeping the RS as a set of
// cards.  The strategy is to cap the size of the fine-grain table,
// deleting an entry and setting the corresponding coarse-grained bit when
// we would overflow this cap.

// We use a mixture of locking and lock-free techniques here.  We allow
// threads to locate PRTs without locking, but threads attempting to alter
// a bucket list obtain a lock.  This means that any failing attempt to
// find a PRT must be retried with the lock.  It might seem dangerous that
// a read can find a PRT that is concurrently deleted.  This is all right,
// because:
//
//   1) We only actually free PRT's at safe points (though we reuse them at
//      other times).
//   2) We find PRT's in an attempt to add entries.  If a PRT is deleted,
//      it's _coarse_map bit is set, so the that we were attempting to add
//      is represented.  If a deleted PRT is re-used, a thread adding a bit,
//      thinking the PRT is for a different region, does no harm.

_coarse_map:粗粒度位图。是一个位图,每一位指向一个region,某一位设置为1代表有指针指向当前region。

_fine_grain_entries:细颗粒入口。哈希表,元素是PerRegionTables(PRTs),我们保存了RS(一个card的set),指向一些regions。策略是根据细粒度表的大小初始化一下,当我们容量超限的时候,删除entry并设置相应的粗粒度的bit。

我们混合使用 加锁机制 和 不加锁机制 。允许线程不加锁读PRTs,但是要修改bucket的话必须获得锁。这意味着任何查找PRT需要用重试获得锁。看起来,读操作可以找到一个并行的时候被删除的PRT是很危险的。但其实没啥问题,因为
1)我们实际上只在安全的时候释放PRT’s ???
2)我们找PRT’s是为了加entries。如果一个PRT被删除了,他相应的_coarse_map的位设置为1,所以我们尝试去加的那个就呈现了。如果删除的PRT被重用,一个线程加了一个bit,认为PRT是给另一个region的,也没有问题

强行翻译,是在看不懂😂

OtherRegionsTable

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值