当前位置:主页   - 电脑 - 程序设计 - C#
CLR探索系列:GC 中的Card table和Brick Table(垃圾回收系列)
来源:网络   作者:   更新时间:2012-02-25
收藏此页】    【字号    】    【打印】    【关闭

  在CLR的垃圾回收子系统中,Card Table和Brick Table是两个比较有意思的表。

  在GC的过程中,一个Heap在运行了一段时间以后,已经分配的空间就会越来越大。在进行了一次局部代或者是完全的垃圾回收以后,就会涉及到一个GC堆的类似碎片整理的概念。整理优化一次GC Heap。同时,这种机制保证了譬如一个IIS Server在长时间的运行过程中的稳定性并且优化了其内存管理。

  这样的好处是显而易见的,但是采用这种解决方案带来的问题也很容易想到:譬如一个存在于GC Heap里面的"Small" Object被移动了,同时它也被其它的object引用。出现了这种情况,在进行GC的时候,就需要遍历整个GC的各种table,root,heap以及保留块来搜索对这个对象的引用,然后更新这个引用。

  这是一个相当消耗CPU资源的动作,幸运的是,GC使用了Card table来减小这个动作带来的系统资源消耗。Card Table缩小了在这个搜索遍历的过程中需要遍历的范围。

  Card table实际上是一块连续的内存区域,做为一个index,这块内存区域里面的每一个bit,都代表了GC Heap中的一块连续的区域,这些bits就组成了一个card table。

  CLR的实现中,Card Table中的一个bit就代表了GC heap里面的128byte的区域。同时,对Card Table的update的动作是以byte为单位的。这就造成了每一次对Card Table的Update,影响到的其实是128*8=1kb这么大的一个区域。

  在DotNet的中间层,但凡涉及到修改一个Object的Ref的CIL Opcodes, 不仅仅会执行份内的修改ref的事情,同时还会很小心的update这个Card Table。

  基于这种设计,在GC的时候,就可以先查找Card Table来看看哪些Object的Ref被修改了,然后只是针对这些区域去进行搜索遍历来Update GC Heap中其它的地方对这个对象的引用。

  这些Bit位的Update,可以由WriteBarrierHelper和ErectWriteBarrier 这两个方法来完成:

//update一个Card table的方法。void GCHeap::ErectWriteBarrier(OBJECTREF *dst, OBJECTREF ref)
{
  // 检查dst的地址是不是在heap之内的地址。  if (((*(BYTE**)&dst) < g_lowest_address)

其它资源
来源声明

版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明