java g1gc-卡片表(ct)与记忆集(rs)

gijlo24d  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(656)

为什么g1需要这两种数据结构?
我的理解是:
ct保存了旧一代参考文献的实际位置信息。
rs是特定于每个区域的,每个区域都有一个与其相关联的rs,它存储指向该区域中对象的外部引用的信息。因此,在导航rs时,使用ct可以找到参考点的实际位置。
为什么rs不能保存所有的信息而不是使用ct?
是不是因为在不同的rss中存储了太多的重复数据?例如,年轻一代有区域a和b,这两个区域中的对象都有与老一代相同的外部参照。在这种情况下,与区域a和b相关联的rss都将存储这个冗余的信息,这个解释正确吗?

8ftvxx2r

8ftvxx2r1#

让我们先把一些事情安排好。一 Card Table 显示此区域可能有传入的引用。它有点像“散列”。对于card表中的单个字节-旧区域中有许多字节。这就像说,如果(理论上)你有一张这样的卡片表(一张卡片被标记为“脏”)

0 1 0 0 0 0

为了这个 1 (脏卡)在扫描新区域时,旧区域中有一个特定的Map也需要扫描。

0          1      0     .....

    0 - 512   512-1024  ...........

因此,脏卡对应于旧一代中的某一部分(从512字节到1024字节),也将被扫描,作为年轻一代扫描的一部分。
g1有区域,现在你需要了解 CT 以及 RS 协同工作。比如说gc扫描 Region1 在这个时间点上,它把这个区域的所有有生命的东西都复制到 Region2 . 同时 Region2 有引用 Region3 . 如果我们使用 CT , Region2 将被标记为“脏”(通过在卡片表中放置特定卡片)。
下一个周期要扫描 Region3 . 你怎么知道的 Region3 知道是否有其他地区可能指向它吗?确实有这样的情况: Region2 引用到 Region3 . 好吧,它可以调查 CT 检查每个脏卡(以及这些脏卡对应的每个区域),看看这里是否有来自这些区域的引用。想一想:为了清楚 Region3 , G1 必须看整个 CT . 在最坏的情况下,它应该扫描整个堆—一个区域。
因此: Remembered Sets . 这些数据结构是基于什么填充的 CT 通过异步线程知道。什么时候 Region2 如果标记为脏,则异步线程将开始计算其 RS . 什么时候 Region3 需要扫描,它的 RS 只会有一个 Region2 .
因此,为了扫描单个区域, G1 只需要调查一下 RS .

相关问题