[Gc] Re: Boehm GC problem

Brian Beuning bbeuning at corecard.com
Sun Dec 29 05:36:39 PST 2013


It is not obvious to me what is wrong with the code.
I glanced at gc_cpp.h and have not read the Dr. Dobbs article.

Here are some things to look into.
1. If your std::string defines its own operator new,
   then "new Boehmable<string>()" was not using the GC allocator.
   (I don't use multiple inheritance.  If both base classes have an
   operator new, I am not sure which base class wins.)
2. gc_cpp.h does define a global operator new() but that does not
   work on all platforms.  It works on UNIX but on Windows each DLL
   can have its own operator new.
3. Since C++ STL containers (like string) do memory allocation,
   you might consider defining a C++ memory allocator class to pass
   to the container templates to control memory allocations.
   (string is usually basic_string<char> and the 3rd argument to
   basic_string<> is the allocator.)
4. This is kind of unlikely, but if the string code maintains a list
   of all the strings that have been constructed then the GC could
   see the list as references and not free the strings.

Brian Beuning

----- Original Message -----
From: "Ivan Maidanski" <ivmai at mail.ru>
To: "Bruce Hoult" <bruce at hoult.org>, "Vadim" <grutargo at gmail.com>
Cc: gc at linux.hpl.hp.com
Sent: Sunday, December 29, 2013 2:33:19 AM
Subject: Re[2]: [Gc] Re: Boehm GC problem


Hi Bruce and Vadim, 

You are right about guarantees. But as I understood the code just a test case showing that all objects of particular type are not collected by GC (on Vadim's target). 

Regards, 
Ivan 


San, 29 Dec 2013, 12:36 +13:00 from Bruce Hoult <bruce at hoult.org>: 







This seems like very bad code to me -- and a bad idea. 


If you need cleanup for all or most of your objects then a tracing GC is probably the wrong way to manage them. You might as well use some reference-counting or pool approach. 


This is advisable from an efficiency point of view, but it is mandatory if you REQUIRE that the cleanup from every object is guaranteed to be run. 


GCs in general do not guarantee to find every inaccessible object on every GC. The documentation for gc_cleanup in gc_cpp.h make it clear that BDWGC in particular does not make a guarantee. 


Most systems with GC don't run the GC on program exit. And nor should they. It's usually a waste of time. But even if you trigger a manual GC there is no guarantee that all cleanup functions will be run. Not even if you call it two or three times. 


If you really need to have a guarantee that cleanup is run for every object, including objects that still exist at program exit, and you want to use GC (any GC, not just this one) then what you have to do is: 


1) add objects requiring cleanup to a global collection (list, hash table etc) that is NOT scanned by the GC. 
2) at program exit call cleanup yourself for every object in that collection. 
3) add a finaliser to each cleanup object that removes the object from the global collection and then calls the cleanup function. 


I've done this in shipping code and it works. Every time. 





On Sun, Dec 29, 2013 at 10:20 AM, Ivan Maidanski < ivmai at mail.ru > wrote: 



Hi Vadim, 

It is better to send questions to the ML ( gc at linux.hpl.com ). Probably someone on the list knows the answer. 

I have tried your sample but it worked for me (on cygwin), the output: 
1000 
1 

1001 
1 

Just for reference, I used the recent BDWGC snapshot and following commands to build the sample: 
gcc -I include -c extra/gc.c 
g++ -I include test_app.cpp gc.o 

[Translated] Fri, 27 Dec 2013, 16:51 +04:00 from Vadim < grutargo at gmail.com >: 







Hi. 
I have an issue with Boehm GC, probably you could help me. 
I found the solution https://www.drdobbs.com/the-boehm-collector-for-c-and-c/184401632?pgno=6 how to use the collector for the std types but it does not work for me. 


The code: 




#include "app.h" I replaced it to: 
#include <iostream> 
#include <stdlib.h> 
#include "gc_cpp.h" 












using namespace std; 


long allocated = 0; 


template<class Super> 
class Boehmable : public Super, public virtual gc_cleanup 
{ 
public: 
Boehmable() : Super(), gc_cleanup() { allocated++; } 
virtual ~Boehmable() { allocated--; } 
}; 


class MyClass 
{ 
public: 
MyClass() {}; 
~MyClass() {}; 
}; 


int main(int argc, char **argv) 
{ 
for (int i = 0; i < 1000; i++) 
{ 
new Boehmable<MyClass>(); 
} 


cout << allocated << endl; // 1000 
GC_gcollect(); 
cout << allocated << endl << endl; // 1 - It works 



for (int i = 0; i < 1000; i++) 
{ 
new Boehmable<string>(); 
} 


cout << allocated << endl; // 1001 
GC_gcollect(); 
cout << allocated << endl << endl; // 1001 - Does not work! 



system("pause"); 


return 0; 
} 


Does not work for list, vector, etc. types neither. 
Regards, 
Ivan 

-- 
This message has been scanned for viruses and 
dangerous content by MailScanner , and is 
believed to be clean. 
_______________________________________________ 
Gc mailing list 
Gc at linux.hpl.hp.com 
https://www.hpl.hp.com/hosted/linux/mail-archives/gc/ 


_______________________________________________ 
Gc mailing list 
Gc at linux.hpl.hp.com 
https://www.hpl.hp.com/hosted/linux/mail-archives/gc/ 


-- 
Иван Майданский 

_______________________________________________
Gc mailing list
Gc at linux.hpl.hp.com
https://www.hpl.hp.com/hosted/linux/mail-archives/gc/



More information about the Gc mailing list