我正在为一种玩具过程语言开发一个业余编译器/解释器,并且我已经实现了我打算探索的大部分功能,除了一个好的垃圾收集算法(类似于 this guy )。我已经阅读了很多关于各种算法的文章,并且对如何实现它们有一个大概的了解。我的语言运行时的早期迭代使用了引用计数,但我放弃了它以学习更高级的东西,所以我现在正在考虑标记和复制压缩算法。
我入门的第一个问题是防止算法在 native 扩展函数(即用 C 编写的函数)中收集“对象”。根集由解释器堆栈上的“对象”和符号表中的“对象”组成,我不应该对这些有太多麻烦,但是,如果容器“对象”是在 C 函数中创建的,然后填充子“对象”,我怎样才能阻止 GC 收集它们,因为它实际上不在解释器堆栈上或绑定(bind)到符号?
使实现 GC 更容易的事情:
- 我的语言中的所有“对象”都是内置类型(例如,非面向对象)
- 解释器堆栈只是一堆指向结构的指针
- 符号表只是指向结构的指针数组
用户代码:
f = open('words.txt', 'r');
lines = readlines(f);
close(f);
解释器(解析后,编译成字节码...):
push
文件名,open_mode- 调用
builtin_fopen
返回一个包含FILE*
的结构 - 将结果存储在符号
f
- 按下符号
f
- 调用
builtin_flines
创建列表类型l
,然后使用 Cfread
读取每一行 文件的字符串类型,将其附加到列表l
- 将结果存储在符号
行
中,依此类推....
现在,如果 GC 在分配包含文件中一行的字符串之一时运行,则根集还没有对 l
的任何引用,因此它应该被收集。
关于如何更好地处理这个问题的任何想法?
最佳答案
- 为解释器的堆分配一个单独的连续分配区域。切勿在竞技场外收集任何东西。
- 您始终拥有竞技场的当前顶部(假设它从较低的地址增长到较高的地址)。顶部以上的所有东西都不可收集,但在根集中考虑。必须分配多个链接对象的内置函数将它们分配到顶部之上,然后将顶部向上移动,以便所有分配的对象立即进入可收集堆。如果收集发生在函数执行过程中,则顶部以上的对象会立即全部移动到新堆。
关于c - 用 C 实现的解释器中的垃圾收集问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15867941/