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

我知道标记和扫术算法。我很好奇的是,它如何仅在整个C内存中拾取指针。我对C内存的理解只是一个简单的字节数组。是否可以确定内存中的值是否是指针?

有帮助吗?

解决方案

Boehm GC是保守的收藏家,这意味着它假设一切都是指针。这意味着它可以找到假阳性引用,例如一个整数,巧合的是在堆中具有地址的价值。结果,某些块可能比非保守收藏家的记忆时间更长。

这是来自 Boehm的页面:

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

  1. 准备每个对象都有一个关联的标记位。清除所有标记位,表明所有对象都可能无法到达。
  2. 标记相标记所有可以通过变量的指针链到达的对象。通常,收集器没有关于指针变量在堆中的位置的真实信息,因此它将所有静态数据区域,堆栈和寄存器视为可能包含指针的所有静态数据区域。代表收集器管理的堆对象中地址的任何位模式都被视为指针。除非客户端程序使收集器可用的堆对象布局信息可用,否则从变量中发现的任何堆对象都会再次扫描。
  3. 扫描阶段会扫描堆的无法访问,因此未标记的对象,并将其返回到适当的免费列表中以进行重复使用。这并不是一个单独的阶段。即使在非增量模式下,通常在发现空的免费列表的分配期间,通常也按需执行操作。因此,扫描阶段非常不可能触及此后不久不会触摸的页面。
  4. 已注册用于最终确定的最终确定阶段无法实现的对象,以在收集器之外完成最终确定。

您还应该知道,BOEHM GC需要给出一组“根”,这是标记算法的起点。堆栈和寄存器自动根源。您需要明确添加全局指针作为根。


编辑:在评论中,人们对保守的收藏家提出了一些担忧。的确,看起来像收集器的堆指针的整数可能会导致内存不释放。这并不像您想象的那样大问题。程序中的大多数标量整数用于计数和尺寸,并且相当小(因此它们看起来不像堆指针)。您主要会遇到包含位图,字符串,浮点数据或任何类似内容的数组的问题。 BOEHM GC让您分配一个块 GC_MALLOC_ATOMIC 向收藏家表明该块将不包含任何指针。如果你看 gc_typed.h, ,您还将找到指定块的哪些部分包含指针的方法。

话虽如此,保守收藏家的基本局限性是,由于指针重写不安全,因此无法在收集过程中安全地移动记忆。这意味着您将不会获得压实的任何好处,例如降低的碎片和改进的缓存性能。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top