[gclist] Mark don't sweep
Charles Fiterman
cef@geode.geodesic.com
Wed, 8 May 1996 07:18:54 -0500
> > Let me suggest my infamous mark and don't sweep collector. Each object
> > starts with a pointer to a descriptor for that object. All methods on
> > the object are pointed to by the descriptor and accept a pointer to the
> > actual object as their first parm. All objects have a length() operator
> > in a consistant place. In OO terms everything is decended from a class
> > that can return its length.
>
> I finally found the time to work through this, and it's really really
> neat!!
>
> Thanks! I'll probably use this in my system! :) It even seems to
> support destructors/finalizers. I can call the destructor for each
> destroyed object during the next allocation pass, which acts as the
> `sweep'. Destructors aren't all called at once, so it's not going to
> be a noticable slowdown, either.
>
> I also like the one-word overhead. The OO `class pointer' idea works
> out well for this if it's a strongly typed system. (My language is
> dynamically typed, so I'll just use a tag word instead.)
Remember that finalizer objects get used as roots without being marked
themselves. This allows finalizer dependencies to work. An addditional
gimmic in addition to a mark() method that marks the stuff an object
uses, a markFinal() that marks the stuff an object's finalizer uses.
Again I don't approve of finalizers. First a garbage collector deletes
objects when they can't effect the program. A finalizer effects the
program. This is original sin. Second finalizers must me prompt and
sure. If you have a chain of finalizer objects they only get killed at
the rate of one per collection cycle. A loop of finalizer objects can
never die.
In a reflexive language, I hope thats your intent, finalizers belong
on top of the object system using it. There are choices of how to
prevent dependency loops. Reference counting is ideal for finalizer
objects because if you can prevent loops it is prompt and sure.
Also by living on top of the object system you can maintain a distinction
between finalizers, which maintain an objects invariants and destructors,
which do not. For example suppose a buffer object with a finalizer
depends on a file object with a destructor and the file object also
depends on the buffer. The loop can be broken by finalizing the buffer
first.
I hope you are interested in partial evaluation technology. I think
any real improvments in language design will come from there.
If you can send me a copy and use my name in the credits.