如何在遍历堆时识别活动对象?

时间:2018-01-22 14:49:36

标签: c algorithm pointers

(上下文:我正在处理的系统已经维护了一种垃圾收集形式。我正在进行压缩。)

大多数压缩算法遵循基本结构:

  1. 查找第一个对象
  2. 将对象移动到堆的开头
  3. 查找第二个对象
  4. 在第一个对象
  5. 之后立即将第二个对象移动到地址
  6. 冲洗并重复
  7. 该算法遵循this paper的2.2节,但使用两个指针,表示为“from”和“to”。本质上,FROM指针遍历堆,直到找到活动对象。然后它将所述对象移动到TO指针。然后TO相应地增加。

    算法很简单,但我还没有找到关于这些指针如何确定什么是“活动对象”的大量信息。 This article讨论了创建一个基本的标记和清除垃圾收集器,它通过堆栈运行,递归地转到每个引用并将它们标记为实时。但是,该文章需要一个已分配的所有对象的链接列表。但是,这是因为作者或多或少地创建了自己的VM。

    我的问题是,有没有办法在C中遍历堆并确定当前对象是否是活动对象?是否有我可以使用的C中已经分配的所有已分配对象的类似链接列表?或者我需要更多的开销吗?

2 个答案:

答案 0 :(得分:2)

  

我的问题是,有没有办法在C中遍历堆并确定当前对象是否是活动对象?

在较高级别,该过程查看所有活动指针并确定每个分配的内存是否可访问。 (请注意,这是非常复杂的C,包括因为指针可以存储在int或其他数据类型中。)如果可以通过指针访问内存,那么它就是" live"用你的条件。如果没有,那么垃圾收集者会认为释放内存是安全的。

如果您要询问C是否具有用于确定是否可以达到某些已分配内存的本机功能,则答案为否。

  

我可以使用C中已有的所有已分配对象的类似链接列表吗?或者我需要更多的开销吗?

同样,如果您正在寻找C本身提供并且您可以访问的链接列表,那么答案是否定的。你需要实现这些东西。

如果您已经看过这个,请原谅我,但如果您想了解其他人是如何做到的话,您可以下载garbage collectors

答案 1 :(得分:1)

TL; DR:这是不可能的。

要做到这一点,你需要解决一些非平凡的问题:

  1. 能够命名堆的活动对象。这意味着在全局变量和堆栈中递归查找并跟踪所有指针。
  2. 向下移动活动对象以创建紧凑堆
  3. 调整程序中的指针以反映移动对象的新位置。
  4. 关于1:在运行时,C语言不能帮助您识别指针类型全局变量的位置。在堆栈上,您可以找到混合物,例如整数,函数调用返回地址或数据指针。对于这两个内存区域,您必须找到一种枚举所有潜在指针值的方法。

    更糟糕的是,指针不仅可以指向数据结构的开头,还可以指向某个内部元素。而且这个指针也使整个对象生活了#34;。

    关于2:这是一个简单的部分,使用你提到的算法。

    关于3:现在您的对象居住在新地址,因此您的旧指针值不再正确(指向旧位置),您必须调整它们。所以再一次,你必须遵循所有的根引用(如1.)并调整所有受移动影响的指针。但是,你无法确定是否例如0x12345678表示为数字整数或(旧位置)地址,将其更改为新位置地址可能会破坏某些计算。