不会暂停的垃圾回收器,C4 The Continuously Concurrent Compacting Collector,by Zing JVM @azulsystems
最近在看GC有很多不错的文章,顺便翻一下C4吧,似乎很神的样子
部分相关资料
GC问题分析相关
垃圾收集器相关
G1是Oracle下一代垃圾回收器,CMS的替代者一个不错的中文介绍
C4是Azulsystems的一篇论文,该公司提供了一个不会stop-the-world的zing JVM,知乎上大名鼎鼎的 @RednaxelaFX 就在这个公司。这是唯一找到的一篇C4中文介绍
隔行如隔山,这个C4的论文实在是看不懂,还好我找到了RednaxelaFX大人的blog。如果你也读不懂,我建议先先去看看
简要翻译
其中很多参考了 @RednaxelaFX的内容以及他的,blog,表示感谢:)
Remembered Set
Remembered Set是在实现部分垃圾收集(partial GC)时用于记录从非收集部分指向收集部分的指针的集合的抽象数据结构。
分代式GC是一种部分垃圾收集的实现方式。当分两代时,通常把这两代叫做young gen和old gen;通常能单独收集的只是young gen。此时remembered set记录的就是从old gen指向young gen的跨代指针。
所以说 Remembered Set是一个抽象的概念,而卡表,就是Remenbered Set的一种实现。
- 粒度问题
所谓粒度问题,就是每个指向yong代的指针到底代表多大的一块空间。所以无论是remembered set还是card table,记录精度都有很大的选择余地:
- 字粒度:每个记录精确到一个机器字(word)。该字包含有跨代指针。
- 对象粒度:每个记录精确到一个对象。该对象里有字段含有跨代指针。
- card粒度:每个记录精确到一大块内存区域。该区域内有对象含有跨代指针。
- 还有其它可能性,任君想像
但一般而言,有一些隐含假设,当提到Remembered Set,一般指的是对象粒度,而卡表一般值一个内存块。
- 实现数据结构
- 对于地址空间较大的情况,可以考虑直接使用指针,也就是一般意义上的Remembered Set
struct RememberedSet {
Object* data[MAX_REMEMBEREDSET_SIZE];
};
或者
typedef char* address;
struct RememberedSet {
address* data[MAX_REMEMBEREDSET_SIZE];
};
- Card Table 则是Remembered Set一种特殊实现,用每个bit隐式代表一块内存区域,所以会格外省空间
struct CardTable {
byte table[MAX_CARDTABLE_SIZE];
};
卡表(card table)
Write Barrier
这篇论文讲的非常清楚,讲了很多实现,说的也很清楚:一篇关于Write Barrier以及Store Buffer的论文