www.digitalmars.com         C & C++   DMDScript  

D - Garbage collection vs. reference counts

reply John Nagle <nagle animats.com> writes:
   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
next sibling parent reply "Walter" <walter digitalmars.com> writes:
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
parent John Nagle <nagle animats.com> writes:
Walter wrote:
 
 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.

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 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
prev sibling parent weingart cs.ualberta.ca (Tobias Weingartner) writes:
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