【发布时间】:2013-04-27 21:01:03
【问题描述】:
我正在用 C++ 编写一个用于编程语言的 VM。该语言是垃圾收集的,因此我在垃圾收集堆中分配了 C++ 类的实例。我正在使用复制收集器,因此当发生 GC 时,这些对象会在内存中移动。这意味着需要更新指向该对象的每个指针。 大部分这些指针都很容易处理,除了一个棘手的:this。考虑:
class SomeObj : public Managed // inheriting from this means it's on the GC heap
{
public:
void method()
{
SomeObj* other = new SomeObj(); // could trigger a GC.
printf("%d\n", someField); // this points to wrong memory
}
private:
int someField;
};
如果我在 GC 堆上的某个对象的实例方法的中间,那么this 指向一些 GC 内存。在此方法的中间可能会发生集合。发生这种情况时,对象将被移动到新位置。但是,由于我们正在调用方法,this 仍然指向旧的错误位置。
我可以通过不在托管内存中的类上使用实例方法来解决这个问题,但我确实喜欢这样的代码更简单。有什么技术可以解决这个问题吗?
【问题讨论】:
-
this只是method的隐藏参数。你可以做你喜欢的事,比如说,你可以delete this;,只要它被适当地分配并且之后你不能(直接或间接地)访问它。 -
请注意,您需要担心的不仅仅是
this,它是任何本地指针变量:void SomeObj::method() { int *x = &m_int; do_something_that_causes_GC(); use(x); }(编译器可能会将x放入寄存器中。) -
如果你有一棵二叉树(每个节点有 2 个指针),什么代码在 GC 后修复所有指针?我认为复制收集器需要引入另一个级别的间接性。
-
如果你知道
this在哪里,你的GC可以更新它,它要么在堆栈上,要么在寄存器中。是你不知道this在哪里的问题吗?如果是这样,那么我认为你有更严重的问题。 -
你看过 Boehm 保守的垃圾收集器吗?做GC但不移动对象,被广泛使用。
标签: c++ garbage-collection programming-languages vm-implementation