(上下文:我正在处理的系统已经维护了一种垃圾收集形式。我正在进行压缩。)
大多数压缩算法遵循基本结构:
该算法遵循this paper的2.2节,但使用两个指针,表示为“from”和“to”。本质上,FROM指针遍历堆,直到找到活动对象。然后它将所述对象移动到TO指针。然后TO相应地增加。
算法很简单,但我还没有找到关于这些指针如何确定什么是“活动对象”的大量信息。 This article讨论了创建一个基本的标记和清除垃圾收集器,它通过堆栈运行,递归地转到每个引用并将它们标记为实时。但是,该文章需要一个已分配的所有对象的链接列表。但是,这是因为作者或多或少地创建了自己的VM。
我的问题是,有没有办法在C中遍历堆并确定当前对象是否是活动对象?是否有我可以使用的C中已经分配的所有已分配对象的类似链接列表?或者我需要更多的开销吗?
答案 0 :(得分:2)
我的问题是,有没有办法在C中遍历堆并确定当前对象是否是活动对象?
在较高级别,该过程查看所有活动指针并确定每个分配的内存是否可访问。 (请注意,这是非常复杂的C,包括因为指针可以存储在int或其他数据类型中。)如果可以通过指针访问内存,那么它就是" live"用你的条件。如果没有,那么垃圾收集者会认为释放内存是安全的。
如果您要询问C是否具有用于确定是否可以达到某些已分配内存的本机功能,则答案为否。
我可以使用C中已有的所有已分配对象的类似链接列表吗?或者我需要更多的开销吗?
同样,如果您正在寻找C本身提供并且您可以访问的链接列表,那么答案是否定的。你需要实现这些东西。
如果您已经看过这个,请原谅我,但如果您想了解其他人是如何做到的话,您可以下载garbage collectors。
答案 1 :(得分:1)
TL; DR:这是不可能的。
要做到这一点,你需要解决一些非平凡的问题:
关于1:在运行时,C语言不能帮助您识别指针类型全局变量的位置。在堆栈上,您可以找到混合物,例如整数,函数调用返回地址或数据指针。对于这两个内存区域,您必须找到一种枚举所有潜在指针值的方法。
更糟糕的是,指针不仅可以指向数据结构的开头,还可以指向某个内部元素。而且这个指针也使整个对象生活了#34;。
关于2:这是一个简单的部分,使用你提到的算法。
关于3:现在您的对象居住在新地址,因此您的旧指针值不再正确(指向旧位置),您必须调整它们。所以再一次,你必须遵循所有的根引用(如1.)并调整所有受移动影响的指针。但是,你无法确定是否例如0x12345678表示为数字整数或(旧位置)地址,将其更改为新位置地址可能会破坏某些计算。