Li Zhen
Li Zhen

Reputation: 95

How to force boehm gc collect all, right before a program exit

I'm learning boehm gc c++ interface now. Not working with it, just curious about. And I follow the official example, writing my classes what could be GCed, in destructor, there is a output, so I can tell whether an instance is GCed or not. But only if I use a loop to create instances as many as something like a thousand or more could ever trigger a gc collection. If the code is simple like this:

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

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

it seems like the destructor is never called. There is no "~test_gc()" outputed. Also the optimization of the compiler is turned off. I did some google, find nearly nothing but the official example.

Please help me how to force a gc collection before a program exit, or tell me how to use it in a correct way if I use it wrong. Many thanks.

Upvotes: 3

Views: 838

Answers (3)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158499

I did some google, find nearly nothing but the official example.

This Dr.Dobb's article on The Boehm Collector for C and C++ has some great examples.

it seems like the destructor is never called.

To quote the article:

but if you want the destructor to be called, you must delete the object yourself.

Upvotes: 3

Chris Dodd
Chris Dodd

Reputation: 126243

The problem is that Boehm's collector is conservative -- it doesn't know what values are live pointers and what values are not, so it scans everything that might be live and treats it as if it was. In your case, since you just called new immediately before GC_collect, its likely there's a pointer to the object in a register or on the stack somewhere that is making the collector think that it is still alive. Try putting the new in some other function called from main, so its frame will be popped before calling 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;
}

This makes it more likely there won't be stray pointers to the object stored somewhere, but there are no guarentees.

Upvotes: 0

Brendan Long
Brendan Long

Reputation: 54242

From the article @Shafik's linked to:

If you need a new class with destructors that the Boehm collector calls automatically, you may subclass the Boehm collector's class gc_cleanup. It's like class gc except that it arranges for the Boehm collector to call the destructor immediately before recycling an instance's memory. Remember that you have no guarantee that all instances will be recycled.

Upvotes: 0

Related Questions