> I think here we're struggling with the atomicity of the garbage collector 
> because the finaliser is special user code that executes inside the garbage 
> collector's "transaction" and that code has all the power and capabilities 
> of any other scheme code.

Finalizer code is in no way special, and there is no specific GC "transaction"
visible from user space. It is just a signal to the user that designates
that an object is about to be dropped from automatic memory management .

> What happens if there are a circular list of objects all of which have 
> finalisers?
> 
> The CHICKEN GC usually handles circular lists well, but when this one is 
> collected (i.e. there are no external strong references to the list 
> anymore) all its members come up for finalisation at the same time.
> 
> Which order are the finalisers called in?

This is undefined.

> 
> ...and which of the other objects can be seen from the object that is 
> finalised first?

I needed to think about this for a moment and you are right in that it
is a special case: an object is subject to reclamation (and finalization),
if it is "about to be dropped". For circular constructs that have no
outside (strong) references pointing to them, they become subject to
finalization in "bulk". In between these objects strong refs may still
exist, so we must relax our mental model a bit: it's not purely dependent
on whether the number of references becomes zero, but a finalizer runs when 
an object is about to be reclaimed, i.e. when the collector can "prove"
this object will be dead if no measures are taken (e.g. medical or 
spiritual assistance), regardless of references to other soon-to-be
dead objects.

> When the managed memory for the circular list is freed it does not matter 
> precisely which order it is freed in because there are no side effects of 
> freeing it and it all happens in a single GC cycle.
> 
> But when the finalisers are run the user's code will see these objects in 
> various different states depending on the order.

The structural state will be identical for all finalizers - a finalizer does 
_not_ represent a special execution state, it is ordinary user code, invoked by 
an oracle (so to speak) that knows that the object will soon be reclaimed.

What _may_ happen is that a finalizer is called for an object which
another finalizer has already "resurrected", at least that is how I understand
it (Peter: correct me if I'm wrong). There is indeed an inconsistency here,
but one I consider acceptable, and which has been the case since 
finalizers were introduced. Weak refs have no relation to that, and clearing
them before finalization removes any additional inconsistencies that might
arise.


cheers
felix


Reply via email to