Java G1GC - 卡片 Table(CT)与记忆集(RS)
Java G1GC - Card Table (CT) vs Remembered Set (RS)
为什么 g1 需要这两种数据结构?
我的理解是:
- CT 保存有关引用在老年代中的实际位置的信息。
- RS是针对每个地区的,每个地区都有一个RS与之关联,它存储了关于
指向该区域中对象的外部引用。因此,在导航 RS 时,实际位置
可以使用CT找到参考。
为什么 RS 不能保存所有信息而不是使用 CT?
是不是因为不同的RS存储了太多的重复数据?
例如 - 新生代有区域 A 和 B,这两个区域中的对象都具有来自老年代的相同外部引用。
在这种情况下,与区域 A 和 B 相关联的 RS 都将存储此冗余信息,此解释是否正确?
让我们先把一些东西整理一下。 Card Table
显示那里 可能 是该区域的传入引用。它确实有点“哈希”。对于卡中的单个字节 table - 在旧区域中有 许多 字节。这就像说,如果(理论上)你有一张卡片 table 看起来像这样(单张卡片被标记为“脏”)
0 1 0 0 0 0
为此1
(脏卡)旧区域中有一个特定的映射也需要在扫描年轻区域时进行扫描。
0 1 0 .....
0 - 512 512-1024 ...........
因此脏卡对应于老年代中的某个部分(从512到1024字节),也将被扫描,作为年轻代扫描的一部分。
G1 有区域,现在您需要了解 CT
和 RS
如何协同工作。假设 GC 在这个时间点扫描 Region1
,它从该区域取出所有存活的东西并复制到 Region2
。同时 Region2
引用了 Region3
。如果我们使用 CT
,Region2
将被标记为“脏”(通过将特定卡片放入卡片 table)。
下一个周期要扫描Region3
。 Region3
如何知道是否有 other 区域可能指向它?确实存在这样的情况:Region2
引用了 Region3
。好吧,它可以查看 CT
并检查每张脏卡(以及这些脏卡对应的每个区域),看看这里是否有来自任何这些区域的引用。想一想:为了清除 Region3
,G1
必须查看 整个 CT
。在最坏的情况下,它应该为单个区域扫描整个堆。
因此:Remembered Sets
。这些数据结构由异步线程根据 CT
知道的内容填充。当 Region2
被标记为脏时,异步线程将开始计算它的 RS
。当Region3
需要扫描时,它的RS
只会有一个条目Region2
。
因此,为了扫描单个区域,G1
仅 需要查看特定的 RS
.
为什么 g1 需要这两种数据结构?
我的理解是:
- CT 保存有关引用在老年代中的实际位置的信息。
- RS是针对每个地区的,每个地区都有一个RS与之关联,它存储了关于 指向该区域中对象的外部引用。因此,在导航 RS 时,实际位置 可以使用CT找到参考。
为什么 RS 不能保存所有信息而不是使用 CT?
是不是因为不同的RS存储了太多的重复数据? 例如 - 新生代有区域 A 和 B,这两个区域中的对象都具有来自老年代的相同外部引用。 在这种情况下,与区域 A 和 B 相关联的 RS 都将存储此冗余信息,此解释是否正确?
让我们先把一些东西整理一下。 Card Table
显示那里 可能 是该区域的传入引用。它确实有点“哈希”。对于卡中的单个字节 table - 在旧区域中有 许多 字节。这就像说,如果(理论上)你有一张卡片 table 看起来像这样(单张卡片被标记为“脏”)
0 1 0 0 0 0
为此1
(脏卡)旧区域中有一个特定的映射也需要在扫描年轻区域时进行扫描。
0 1 0 .....
0 - 512 512-1024 ...........
因此脏卡对应于老年代中的某个部分(从512到1024字节),也将被扫描,作为年轻代扫描的一部分。
G1 有区域,现在您需要了解 CT
和 RS
如何协同工作。假设 GC 在这个时间点扫描 Region1
,它从该区域取出所有存活的东西并复制到 Region2
。同时 Region2
引用了 Region3
。如果我们使用 CT
,Region2
将被标记为“脏”(通过将特定卡片放入卡片 table)。
下一个周期要扫描Region3
。 Region3
如何知道是否有 other 区域可能指向它?确实存在这样的情况:Region2
引用了 Region3
。好吧,它可以查看 CT
并检查每张脏卡(以及这些脏卡对应的每个区域),看看这里是否有来自任何这些区域的引用。想一想:为了清除 Region3
,G1
必须查看 整个 CT
。在最坏的情况下,它应该为单个区域扫描整个堆。
因此:Remembered Sets
。这些数据结构由异步线程根据 CT
知道的内容填充。当 Region2
被标记为脏时,异步线程将开始计算它的 RS
。当Region3
需要扫描时,它的RS
只会有一个条目Region2
。
因此,为了扫描单个区域,G1
仅 需要查看特定的 RS
.