编译为C时的垃圾回收 [英] Garbage collection when compiling to C

查看:70
本文介绍了编译为C时的垃圾回收的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将垃圾收集语言编译为C时,垃圾收集有哪些技术?我知道两个:

What are the techniques of garbage collection when compiling a garbage collected language to C? I know of two:

  1. 维护一个影子堆栈,该影子堆栈将所有根显式保存在数据结构中

  1. maintain a shadow stack that saves all roots explicitly in a data structure

使用Boehm的保守垃圾收集器

use a conservative garbage collector like Boehm's

第一种方法很慢,因为您必须维护阴影堆栈.潜在地,每次调用函数时,都需要将局部变量保存在数据结构中.

The first technique is slow, because you have to maintain the shadow stack. Potentially every time a function is called, you need to save the local variables in a data structure.

第二种技术也很慢,并且由于使用保守的垃圾收集器,因此固有地无法回收所有垃圾.

The second technique is also slow, and inherently does not reclaim all garbage because of using a conservative garbage collector.

我的问题是:编译为C时垃圾收集的最新状态是什么.请注意,我并不是在用C进行编程时(这是Boehm垃圾收集器的目标)的一种便捷方式来进行垃圾收集,只是编译为C 时进行垃圾回收的一种方法.

My question is: what is the state of the art of garbage collection when compiling to C. Note that I do not mean a convenient way to do garbage collection when programming in C (this is the goal of Boehm's garbage collector), just a way to do garbage collection when compiling to C.

推荐答案

可能每次调用函数时,都需要将局部变量保存在数据结构中.

Potentially every time a function is called, you need to save the local variables in a data structure.

不,您不需要-可以将局部变量留在C堆栈中并仍然对其进行遍历:将所有引用变量放入数组中,并向该指针添加指向链表的指针,在该链表中添加节点时输入新的堆栈框架.

No, you don't - you can leave the local variables on the C stack and still iterate through them: put all reference variables in an array and add a pointer to that to a linked list to which you append a node when entering a new stack frame.

模型:

struct vm
{
    struct scope *root;
};

struct scope
{
    struct scope *prev, *next;
    size_t size;
    struct ref *refs;
};

void foo(struct vm *vm, struct scope *caller)
{
    struct ref local_refs[42];
    struct scope scope = {
        caller, NULL, sizeof local_refs / sizeof *local_refs, local_refs };

    caller->next = &scope;

    // ...

    caller->next = NULL;
}

但是,如果要支持延续/非本地跳转,则必须跳过一些主要的障碍.在这种情况下,对所有内容进行堆分配会更容易.

However, you'll have to jump through some major hoops if you want to support continuations/non-local jumps. In that case, it's easier to heap-allocate everything.

这篇关于编译为C时的垃圾回收的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆