D - Garbage collection vs. reference counts
- John Nagle (21/21) Oct 03 2001 I've proposed a way to tighten up C++ using reference-counted
- Walter (4/23) Oct 05 2001 I never liked the resurrection possibility, either.
- John Nagle (50/65) Oct 06 2001 It's easy to do. There have been many (too many) smart
- weingart cs.ualberta.ca (Tobias Weingartner) (4/12) Oct 05 2001 There are ways around this. Read some of the more
I've proposed a way to tighten up C++ using reference-counted allocation plus compiler support for temporary, immutable raw pointers. See http://www.animats.com/papers/languages/index.html This turns out to be a tough retrofit to C++, but might be worth looking at for D. Garbage collected environments introduce finalizers, which have terrible semantics. They're ugly enough in Java, but take a look at "Microsoft Managed Objects for C++", which shows where the combination of raw pointers, garbage collection, and finalizers leads. You can "return an object to life" from the finalizer, leading to some strange semantics. Incidentally, conservative garbage collection runs into problems as the address space fills up. With 32-bit pointers, you have a 4GB address space. You're likely today to have a significant fraction of that space with real memory behind it. So the odds of a random bit pattern being construed as a pointer become quite high. And the transition to 64 bits on the desktop is still a ways off. John Nagle Animats
Oct 03 2001
John Nagle wrote in message <3BBB4600.C382802 animats.com>...I've proposed a way to tighten up C++ using reference-counted allocation plus compiler support for temporary, immutable raw pointers. See http://www.animats.com/papers/languages/index.html This turns out to be a tough retrofit to C++, but might be worth looking at for D.Thanks. I did something similar in C years ago with the __handle pointers.Garbage collected environments introduce finalizers, which have terrible semantics. They're ugly enough in Java, but take a look at "Microsoft Managed Objects for C++", which shows where the combination of raw pointers, garbage collection, and finalizers leads. You can "return an object to life" from the finalizer, leading to some strange semantics.I never liked the resurrection possibility, either.Incidentally, conservative garbage collection runs into problems as the address space fills up. With 32-bit pointers, you have a 4GB address space. You're likely today to have a significant fraction of that space with real memory behind it. So the odds of a random bit pattern being construed as a pointer become quite high. And the transition to 64 bits on the desktop is still a ways off.Reference counting has its own problems, like inability to deal with cycles.
Oct 05 2001
Walter wrote:John Nagle wrote in message <3BBB4600.C382802 animats.com>...It's easy to do. There have been many (too many) smart pointer libraries for C++ The problem is doing it safely and efficiently. That's what I've been trying to address. The key idea is introducing local references which can't outlive the object they reference. Once such a local reference has been created, its use requires no further reference counting. That's what the "auto pointer" scheme I proposed is all about. From a compiler perspective, it's also worth considering the automatic introduction of such references, as a way of hoisting reference counting out of loops.I've proposed a way to tighten up C++ using reference-counted allocation plus compiler support for temporary, immutable raw pointers. See http://www.animats.com/papers/languages/index.html This turns out to be a tough retrofit to C++, but might be worth looking at for D.Thanks. I did something similar in C years ago with the __handle pointers.I never liked the resurrection possibility, either.Other troubles with finalizers involve locking (finalizers introduce concurrency, since they can in be called from another thread) and exceptions (who catches an exception from a finalizer?). But the big problem is that finalizers are called late, from GC, and so can't be used for holding open descriptors, locks, and other non-memory assets which must be released when unneeded. Having both finalizers and destructors in the same language is even worse. If you have finalizers only, you need some way to have actions take place at scope exit, like Common LISP's (WITH_OPEN_FILE file block) construct.Reference counting has its own problems, like inability to deal with cycles.Cycles are annoying, but at least have comprehensible semantics. Weak pointers (as used in Perl, not as used in Java) help deal with cycles. True cycles of peers are rare; the most common case is a back pointer to a superior object. Such back pointers should be weak pointers. That deals with the most common case effectively. When you truly have interlinked peers, the proper approach is to have them all owned by a collection in some superior object, and then have all the inter-object links be weak. Weak and strong pointer semantics are worth thinking about. First, you can't dereference a weak pointer; you have to take a strong pointer from it first. This may be done through an implicit conversion, but it has to be done, so that the target object can't go away while referenced. Attempts to dereference invalid weak pointers must throw. If you do it that way, destructor sequencing is automatically correct. If A has a strong pointer to B, and B has a weak pointer to A, then removing the last strong reference to A causes A's destructor to be called. A's destructor can make calls to B's methods, but B's weak pointer back to A is invalid (because A's strong reference count is 0) so B can't call A's methods while A's destructor is running. So you can't get accidental re-entry into an object during destruction. So reference counted weak and strong pointers can be efficient, safe, and have clean semantics. John Nagle Animats
Oct 06 2001
In article <3BBB4600.C382802 animats.com>, John Nagle wrote:Incidentally, conservative garbage collection runs into problems as the address space fills up. With 32-bit pointers, you have a 4GB address space. You're likely today to have a significant fraction of that space with real memory behind it. So the odds of a random bit pattern being construed as a pointer become quite high. And the transition to 64 bits on the desktop is still a ways off.There are ways around this. Read some of the more advanced garbage collection papers out there. --Toby.
Oct 05 2001