Finalization
Andreas Raab
andreas.raab at gmx.de
Sun Mar 26 01:28:03 UTC 2006
Hi -
No I'm not talking about Ephemerons - having done an implementation for
fun in the past I'm quite aware about the differences ;-) What I'm
proposing here is simply a (precise) notification mechanism for object
finalization.
Cheers,
- Andreas
Nicolás Cañibano wrote:
> Andreas,
> It sounds to me like you are talking about Ephemerons, am I
> right? VW has support to it, what about Squeak? I have easily
> implemented a Finalizer like the one you mentioned, relying in the
> Ephemeron mechanism. I could give you more details if you want.
>
> Best regards,
> Cani
>
> ----- Original Message -----
> From: Andreas Raab <andreas.raab at gmx.de>
> To: The general-purpose Squeak developers list <squeak-dev at lists.squeakfoundation.org>
> Date: Saturday, March 25, 2006, 12:23:12 AM
> Subject: Finalization (was: Re: [Seaside] WeakArray (again))
>
>> David Shaffer wrote:
>>> \begin{amateurHour}
>>>
>>> It seems to me that the notification needs to be changed to actually
>>> queueing information about the objects which the GC deams
>>> un(strongly)reachable. I spent some time staring at
>>> ObjectMemory>>sweepPhase, #finalizeReference: and #signalFinalization:
>>> which seem to be the cornerstones of this process. All that
>>> #signalFinalization: is currently doing is signaling a semaphore (well,
>>> indicating that one should be "signaled" later). Why not keep a list of
>>> (oop,i) [i is the offset of the weak reference in the oop] pairs and
>>> somehow communicate those back to a Smalltalk object? As a total VM
>>> novice it just seems too simple ;-) What I think I would do is
>>> associate a queue like thing with every weak reference container. Then
>>> when an object becomes GC-able I'd place the (oop,i) pair in that shared
>>> queue. What I need is someone to hold my hand through...
>>>
>>> ...designing this "queue like thing". How about a circular array which
>>> can only be "read" (move the read index) by ST code and only be written
>>> by the VM code? This avoids a lot of concurrency issues. Are there any
>>> examples like this in the VM?
>>>
>>> \end{amateurHour}
>
>> What you've described is not a bad idea in general (and it's probably
>> what VW does) but there are things that I don't like about it. For
>> example, part of why the finalization process takes so much time is that
>> there are so many weak references lost that we don't care about - the
>> whole idea that just because you use a weak array you need to know when
>> its contents goes away is just bogus. Secondly, once you start relying
>> on "accurate" finalization information you should really make sure it's
>> accurate (e.g., one signal/entry per finalized object). And once you do
>> that you need to deal with the ugly corner cases of an overflow of the
>> finalization queue (and the effect that you probably can't allocate any
>> larger one because the GC you're currently in was triggered by a low
>> space condition to begin with ;-) Nasty, nasty issues.
>
>> Having said that, let me propose a mechanism that (I think) is
>> fundamentally different and fundamentally simpler. Namely, to make the
>> requirement that you only get notifications for the finalization of
>> objects that you explicitly register for by creating a "finalizer"
>> object, e.g., an observer which is allocated before it's ever needed.
>> This simple change avoids both the problem of GC needing to allocate
>> memory when there is none as well as sending notifications about
>> finalizations that nobody cares about, which are both very desirable
>> properties. When the object becomes eligible for garbage collection, the
>> finalizer is then put into a list of objects that have indeed been
>> finalized and the finalization process simply pulls them out of the
>> queue and sends #finalize to them.
>
>> In its simplest form, this could mean a finalizer is a structure with
>> (besides the prev and next links for putting it into a structore) two
>> slots a "weak" slot for the object being guarded and a "strong" slot for
>> the object performing the finalization (its #finalizer). When the
>> garbage collector runs across a Finalizer and notices its observed value
>> is being collected, it can simply put the finalizer into the
>> finalization list and is done. (btw, this scheme is *vastly* easier to
>> implement than your proposed scheme since everything is pre-allocated
>> and you only move the object from one list to another).
>
>> But while we're at it, we could also shoot a little bit further and get
>> away from post-mortem finalization (which I find a highly overrated
>> concept in practice). The only thing we'd change in the above is that
>> the garbage collector would now also transfer the object from the "weak"
>> into the "strong" slot[*1]. This makes the finalizer the sole last
>> reference to the object. If the finalizer drops it, it's gone. If the
>> finalizer decides to store it, it will survive. Lots of interesting
>> possibilities and much cleaner since you gain access to the full context
>> of the object and its state.
>
>> [*1] The easiest way to do this would be to simply clone the object but
>> unfortunately this also has the unbounded memory problem so something a
>> bit more clever might be required. Basically we really want *all*
>> references to the object except from the finalizer to be cleaned up.
>
>> Note that weak arrays or other weak classes wouldn't be affected at all
>> by this since only Finalizers get the notifications - all other weak
>> classes would simply drop the references when they get collected and
>> never get notified about anything.
>
>> Cheers,
>> - Andreas
>
> X --------------------------
>
>
>
More information about the Squeak-dev
mailing list
|