3

我现在正在学习 boehm gc c++ 接口。不使用它,只是好奇。我按照官方的例子,写我的类可以被GC,在析构函数中,有一个输出,所以我可以判断一个实例是否被GC。但只有当我使用循环创建多达一千个或更多的实例时才能触发 gc 集合。如果代码像这样简单:

class test_gc : public gc
{
public:
    ~test_gc()
    {
        cout << "~test_gc()" << endl;
    }
};

int main()
{
    GC_INIT();
    ::new (GC) test_gc();
    GC_gcollect();
    return 0;
}

似乎从未调用过析构函数。没有“~test_gc()”输出。编译器的优化也被关闭。我做了一些谷歌,除了官方示例之外几乎什么也没找到。

请帮助我如何在程序退出之前强制 gc 收集,或者如果我使用错误,请告诉我如何以正确的方式使用它。非常感谢。

4

3 回答 3

3

我做了一些谷歌,除了官方示例之外几乎什么也没找到。

这篇Dr.Dobb's关于C 和 C++ 的 Boehm 收集器的文章有一些很好的例子。

似乎从未调用过析构函数。

引用文章:

但是如果你想调用析构函数,你必须自己删除对象。

于 2013-05-29T02:54:42.373 回答
0

从@Shafik 链接到的文章中:

如果您需要一个带有 Boehm 收集器自动调用的析构函数的新类,您可以将 Boehm 收集器的类 gc_cleanup 子类化。它类似于 gc 类,只是它安排 Boehm 收集器在回收实例内存之前立即调用析构函数。请记住,您不能保证所有实例都会被回收。

于 2013-05-29T02:59:01.187 回答
0

问题是 Boehm 的收集器是保守的——它不知道哪些值是活动指针,哪些值不是,所以它扫描所有可能是活动的并将其视为活动。在您的情况下,由于您刚刚new在之前调用过GC_collect,因此很可能在寄存器或堆栈中某个地方存在指向该对象的指针,这使收集器认为它还活着。尝试将其new放入其他调用 from 的函数中main,以便在调用之前弹出其框架GC_collect

int func()
{
   ::new (GC) test_gc();
   return 0; /* overwrite the return value register so it doesn't contain the return value from ::new */
}
int main()
{
    GC_INIT();
    func();
    GC_gcollect();
    return 0;
}

这使得它更有可能不会有指向存储在某处的对象的杂散指针,但没有保证。

于 2013-05-29T14:17:42.177 回答