繁体   English   中英

Boehm GC如何为C程序工作?

[英]How does Boehm GC work for C program?

我检查了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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM