我正在尝试在C中实现一个简单的标记和清除垃圾收集器。算法的第一步是找到根。所以我的问题是如何在C程序中找到根源?
在使用malloc的程序中,我将使用自定义分配器。这个自定义分配器是从C程序调用的所有东西,也可以是自定义的init()。
垃圾收集器如何知道程序中所有指针(根)的含义?另外,给定一个自定义类型的指针,它如何得到所有指针?
例如,如果有一个指向类列表的指针p,其中有另一个指针...说q。垃圾收集器如何知道它,以便它可以标记它?
更新:如果我在初始化时将所有指针名称和类型发送到GC怎么样?类似地,也可以发送不同类型的结构,以便GC可以遍历树。这甚至是一个理智的想法,还是我只是疯了?
答案 0 :(得分:5)
根基本上都是静态和自动对象指针。静态指针将在加载模块内链接。必须通过扫描堆栈帧找到自动指针。当然,您不知道自动指针在堆栈帧中的位置。
一旦你有了根,你需要扫描对象并找到它们内的所有指针。 (这将包括指针数组。)为此,您需要识别类对象,并以某种方式从中提取有关指针位置的信息。当然,在C语言中,许多对象都不是虚拟的,并且在它们中没有类指针。
祝你好运!!已添加:一种可能模糊地让你的任务成为可能的技术是“保守”垃圾收集。由于您打算拥有自己的分配器,您可以(以某种方式)跟踪分配大小和位置,因此您可以从存储中挑选任何指针大小的块并询问“这可能是指向我的某个对象的指针吗?”当然,您可以永远不知道,因为随机数据可能“看起来像”指向您的某个对象的指针,但您仍然可以通过此机制扫描一大块存储(如调用堆栈中的帧,或者单个对象)并识别可能地址的所有可能对象。
使用保守的收集器,您无法安全地执行对象重定位/压缩(在移动对象时修改对象的指针),因为您可能会意外地修改看起来像对象指针的“随机”数据,但实际上对某些数据来说是有意义的数据应用。但是,您可以识别未使用的对象并释放它们占用的空间以便重复使用。通过适当的设计,可以实现非常有效的非压缩GC。
(但是,如果您的C版本允许未对齐的指针扫描可能会非常慢,因为您必须尝试字节对齐的每个变体。)