如何在程序退出前强制进行Boehm GC全垃圾回收?

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_cleanup创建的。 - Li Zhen
3个回答

3
我做了一些谷歌搜索,发现除了官方示例几乎没有什么内容。
这篇关于C和C ++的Boehm收集器的Dr.Dobb's文章有一些很好的例子。
似乎析构函数从未被调用。
引用文章的话:
但是,如果您希望调用析构函数,则必须自己删除对象。

1
非常感谢。我明白了,所以gc只处理内存,而不是其中保存的数据,甚至没有析构函数。此外,gc无法保证每个实例的收集顺序。 - Li Zhen

0
问题在于Boehm的垃圾收集器是保守的——它不知道哪些值是活指针,哪些值不是,因此它会扫描所有可能是活的东西,并将其视为是活的。在您的情况下,由于您刚刚在GC_collect之前立即调用了new,所以很可能在寄存器或堆栈中有一个指向该对象的指针,这使得收集器认为它仍然是活的。尝试将new放在从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;
}

这样做可以更有可能避免对象存储在某个地方的杂散指针,但并不保证。


0

从@Shafik链接的文章中:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接