`
chaisencs
  • 浏览: 8239 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

谈一下对hotspot虚拟机中CMS收集器要设置Mod Union Table的理解

阅读更多
这个问题想了很久,脑子想迷糊了都,不知道理解得对不对。

在CMS的并发标记阶段,可能会出现两个并发问题:

第一,CMS在执行并发标记,同时,应用在修改老年代中对象的引用。这时候,老年代的引用状态会发生改变,所以CMS要想办法把这种改变记录下来。CMS使用card table来记录这些改变,把发生改变的对象所在的card标记为dirty,然后在最终标记阶段再次扫描这些标记为dirty的card。(不过这样也会产生浮动垃圾)

第二,CMS在执行并发标记,同时,新生代GC开始运行。注意,新生代GC也需要扫描上述的card table(据我理解这个card table只有一个),在扫描的时候,也是要对标记为dirty(这里的dirty是在引用赋值的时候标记的,具体是先插入一个write barrier,然后判断如果左值是老年代的引用,右值是新生代的引用,那么就把这个card标记为dirty)的card进行分析,如果这个card没有对新生代的引用了,那么新生代GC就会把它标记为clean,但是这样导致CMS收集器在最终标记阶段无法扫描这个card。
那这样到底有影响吗?想象一种可能的情况,就是在CMS在执行并发标记的时候,其他线程先改变了一个card里面的对象引用,然后新生代GC开始运行(这时CMS仍然在执行并发标记),新生代GC如果扫描到这个dirty card不再有新生代的引用,那么就把它标记为clean。这个时候就会出现了标记遗漏的情况了。

为了解决上述的问题,Mod Union Table被引入了,它是一个位向量,每个单元的大小只有1位,每个单元对应一个card(card的大小是512字节,cardtable每一个单元的大小是1个字节),在新生代GC处理dirty card之前,先把该card在Mod Union Table里面的对应项置位。这样,CMS在执行最终标记阶段的时候,就会扫描Mod Union Table和card table里面被标记的项。


另外,对于card table中每一个单元的取值,新生代GC和CMS所设置的dirty应该有所区别,意思就是说,它们两个用不同的值来代表drity这个状态。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics