Boehm GC如何为C程序工作?

时间:2011-01-25 16:50:04

标签: c garbage-collection principles boehm-gc

我检查了Boehm GC。用于C / C ++的GC。

我知道标记和扫描算法。我很好奇的是它如何只在整个C内存中获取指针。我对C内存的理解只是一个普通的字节数组。是否有可能确定内存中的值是否为指针?

1 个答案:

答案 0 :(得分:18)

Boehm GC是一个保守的收集器,这意味着它假设一切都是指针。这意味着它可以找到误报引用,就像一个巧合地具有堆中地址值的整数。结果,一些块可能比非保守的收集器在内存中保留的时间更长。

以下是Boehm's page的说明:

  

垃圾收集器使用修改过的   标记扫描算法。从概念上讲   大致分四个阶段运作   偶尔作为一部分进行   内存分配:

     
      
  1. 准备每个对象都有一个关联的标记位。清除所有标记   位,表示所有对象都是   可能无法到达。
  2.   
  3. 标记阶段标记所有可通过链接到的对象   来自变量的指针。通常是   收藏家没有真正的信息   关于指针的位置   堆中的变量,因此它可以查看所有   静态数据区,堆栈和   注册为可能含有   指针。任何位模式   表示堆内的地址   收集器管理的对象是   被视为指针。除非是客户   程序已经进行了堆对象布局   可用的信息   collector,找到的任何堆对象   可以从变量再次访问   同样扫描。
  4.   
  5. 扫描阶段扫描堆是否无法访问,因此没有标记,   对象,并将它们返回给   适当的免费清单供重复使用这个   并不是一个单独的阶段;甚至   在非增量模式下,这是   操作通常在   分配期间的需求   发现一个空的空闲列表。就这样   扫相不太可能触及   一个本来不会的页面   此后不久就触及了。
  6.   
  7. 结束阶段已注册的无法访问的对象   最终确定排队   在收藏家之外完成。
  8.   

你还应该知道Boehm GC需要给出一组“根”,它们是标记和扫描算法的起点。堆栈和寄存器是自动根。您需要将全局指针显式添加为根。


编辑:在评论中,一般关注保守派收藏家的一些担忧。确实,看起来像收集器的堆指针的整数会导致内存不被释放。这并不像你想象的那么大。程序中的大多数标量整数用于计数和大小,并且相当小(因此它们看起来不像堆指针)。您将主要遇到包含位图,字符串,浮点数据或任何类型的数组的问题。 Boehm GC允许您使用GC_MALLOC_ATOMIC分配一个块,该块向收集器指示该块不包含任何指针。如果查看gc_typed.h,您还可以找到方法来指定块的哪些部分可能包含指针。

也就是说,保守派收集器的一个基本限制是它在收集过程中不能安全地移动内存,因为指针重写是不安全的。这意味着您将无法获得压缩的任何好处,例如降低碎片和提高缓存性能。