Re: A garbage collector for C++
"Boehm, Hans" <[email protected]> Wed, 26 Apr 2006 11:50:44 -0700
| Newsgroups | gmane.comp.programming.garbage-collection.general |
|---|---|
| Message-ID | <65953E8166311641A685BDF71D865826ACE17D@cacexc12.americas.cpqcorp.net> |
I think you're unfortunately propagating some very commonly held misconceptions here. In particular: 1) Deterministic or synchronous finalization is NOT DESIRABLE unless the programmer knows exactly which finalizers may be run at which program point. In particular, in a multithreaded lock-based system, you need to know which locks may be acquired where. If you have to say that any pointer assignment may acquire any locks as a result of reference-count-driven destructor calls, there's no chance to avoid deadlock. (If you are writing single-threaded or transactional memory programs, in this case the same issues apply, but they're slightly harder to state.) In nearly all realistic cases, you want finalizers to run in their own thread, so that they can independently block on locks. This is different from the usual RAII scheme for objects whose lifetimes are similar to those of a stack frame and destructor invocations are predictable and understood by the programmer. For details, see my POPL 2003 paper. Almost all early Java implementations initially ran finalizers in a mutator thread. The results were occasional deadlocks or worse. We've been there and tried that. (In spite of the fact that the original Java spec clearly disallowed running finalizers in clients.) This is not to say that synchronous destruction is a bad idea. If you're using a destructor to release a lock, it's exactly what you need. But in these cases, you know where the destructor is being run. For general finalizers, you don't. C++ destructors and finalizers are really different. 2) Classic reference counting does exhibit substantial pauses when complex data structures are dropped. You can avoid this by delaying deallocation and destructor invocation. But if you really want to limit the time spent in recursive deallocation to a constant, independent of the size of objects you are allocating, you can potentially square the heap size of the process. Unavoidably. For details, see Bacon, Cheng, Rajan, "A Unified Theory of Garbage Collection", OOPSLA 2004, and my POPL 2004 paper. Hans ________________________________ From: [email protected] [mailto:[email protected]] On Behalf Of Guo Mingnan Sent: Monday, April 24, 2006 5:11 PM To: [email protected] Subject: [gclist] A garbage collector for C++ Hello everyone. I have written a garbage collector for standard C++ application. It has following main features. 1) Deterministic Finalization Providing deterministic finalization, the system can manage resources as well as objects. The programming style is clear and easy, conforming to RAII (Resource Acquisition Is Initialization) idiom of C++ programmers. The memory usage is very efficient, acyclic garbage is reclaimed when the last reference to it is removed. A well-designed application, which eliminates cyclic data structure, does not need expensive garbage collection and is always running with minimum memory usage. 2) Accurate GC for C++ It is a fully accurate tracing garbage collector. All garbage objects are identified by the system, no conservative stack frame guessing. Fully C++ optimization compiler support. 3) No Pause (less than 1us) In this system, all application codes automatically become fully interruptible and GC-Safe. Therefore, scavenge can start at any place without rendezvous requirement. A special concurrent tracing garbage collector successfully evades root-set scanning, and does not cause suspension of any thread at all. In the worst racing case, the latency is less than one microsecond (not millisecond). It is very satisfied for real-time systems. 4) Small Overhead The runtime cost of application threads is far less than a normal reference counting. If there is no concurrently running scavenging action, there is no write-barrier overhead, no strong memory ordering requirement, no synchronization overhead. There is no extra code or data structure injected for GC safe point. The whole system does not require strong memory ordering, it is suitable for most modern processor architecture. Multi-processor concurrency can be further exploited by the multi-threading property of mutator and collector. 5) Compatible Object Model As well as conventional C++, the system supports multiple-inheritance, object as member variables, and object arrays. Support C++ raw pointer, unions, bit-fields and hidden pointers. Support C++ templates. Support native object and tracing. 6) Widely Portable Even conducting an accurate tracing, the system does not require any special information from compiler. Application can use any standard C++ compiler, such as Visual C++ 8 and GCC. There is no special platform requirement, such as Win32 system call: SuspendThread, GetWriteWatch, etc. Even virtual memory support is not necessary. Thus, it can be ported to a wider area. Does anyone have any interest in this system? Any comments are welcome! Mingnan G. [email protected] ________________________________ 雅虎1G免费邮箱百分百防垃圾信 <http://cn.mail.yahoo.com>