68.记忆集(remembered set)和写屏障(write barrier)
1.记忆集(remembered set
)
问题:G1
将堆区划分成多个region
,一个region
不可能是独立的,它其中存储的对象可能被其他任意region
(这些region
可能Old
区或者Eden
区)中的对象所引用。这样一来,在进行YGC
的时候,判断Eden
区中的一个对象是否存活时,需要去扫描所有的region
(包括Old
区,Eden
区等),导致了在回收年轻代的时候,还需要扫描老年代,同时扫描表示所有Eden
区和Old
区的region
,相当于做了一个全堆扫描,这会大大降低YGC
的效率。
为了解决上面的问题,提出了remembered set
的概念。
写屏障(write barrier)
- 写屏障的概念比较简单,就是对一个对象引用进行写操作(即引用赋值)之前或之后附加执行的逻辑。
写屏障与记忆集:
每次在对一个对象引用进行赋值的时候,会产生一个写屏障中断操作,然后检查将要写入的引用指向的对象是否和该引用当前指向的对象处在不同的region
中;如果不同,通过CardTable
将相关的引用信息记录到Remembered set
中;当进行垃圾收集时,在GC
根节点的枚举范围内加入Remembered Set
,就可以保证不用进行全局扫描。
记忆集是什么?
如下图所示,每个region
都有一个记忆集(Rset
),记忆集会记录下当前这个region
中的对象被哪些对象所引用。例如,region2
中的两个对象分别被region1
中的对象和region3
中的对象所引用,那么,region2
的记忆集记录的就是region1
和region3
中的引用region2
的对象的引用。
这样一来在回收region2
的时候,就不用扫描全部的region
了,只需要访问记忆集,就知道当前region2
里面的对象被哪些对象所引用,判断其是不是存活对象。