Eon*_*nil 14 c garbage-collection principles boehm-gc
我检查了Boehm GC.用于C/C++的GC.
我知道标记和扫描算法.我很好奇的是它如何只在整个C内存中获取指针.我对C内存的理解只是一个普通的字节数组.是否有可能确定内存中的值是否为指针?
Jay*_*rod 18
Boehm GC是一个保守的收集器,这意味着它假设一切都是指针.这意味着它可以找到误报引用,就像一个巧合地具有堆中地址值的整数.结果,一些块可能比非保守的收集器在内存中停留的时间更长.
以下是Boehm页面的描述:
垃圾收集器使用修改的标记扫描算法.从概念上讲,它大致分四个阶段运行,偶尔作为内存分配的一部分执行:
- 准备每个对象都有一个关联的标记位.清除所有标记位,表示所有对象都可能无法访问.
- 标记阶段标记可通过变量指针链到达的所有对象.收集器通常没有关于堆中指针变量位置的真实信息,因此它将所有静态数据区域,堆栈和寄存器视为可能包含指针.表示收集器管理的堆对象内的地址的任何位模式都被视为指针.除非客户端程序已将堆对象布局信息提供给收集器,否则将再次以类似方式扫描发现可从变量访问的任何堆对象.
- 扫描阶段扫描堆中的不可访问的,因此未标记的对象,并将它们返回到适当的空闲列表以供重用.这不是一个单独的阶段; 即使在非增量模式下,这也是通常在发现空闲列表的分配期间按需执行操作.因此,扫描阶段不太可能触及此后不久就不会被触摸的页面.
- 结束阶段已注册完成的无法访问的对象将排队,以便在收集器外部完成.
您还应该知道Boehm GC需要给出一组"根",它们是标记和扫描算法的起点.堆栈和寄存器是自动根.您需要显式添加全局指针作为根.
编辑:在评论中,一般关注保守收藏家的一些担忧.确实,看起来像收集器的堆指针的整数会导致内存不被释放.这并不像你想象的那么大.程序中的大多数标量整数用于计数和大小,并且相当小(因此它们看起来不像堆指针).您将主要遇到包含位图,字符串,浮点数据或任何类型的数组的问题.Boehm GC允许您分配一个块,GC_MALLOC_ATOMIC向收集器指示该块不包含任何指针.如果查看gc_typed.h,您还可以找到指定块的哪些部分可能包含指针的方法.
也就是说,保守收集器的一个基本限制是它在收集过程中不能安全地移动内存,因为指针重写是不安全的.这意味着您将无法获得压缩的任何好处,例如降低碎片和提高缓存性能.