[Vm-dev] An idea about better finalization support

Andreas Raab andreas.raab at gmx.de
Thu Apr 23 02:41:38 UTC 2009


This is actually quite similar to what I thought about for a more robust 
finalization solution. My thought was that you could just use linked 
lists (which have operations that are already supported by the VM for 
process management) and then make a weak subclass of Link that holds the 
object to be watched plus the finalizer for the object. When the VM 
traces such a link it puts it onto a VM-level finalization list and 
signals the finalization semaphore. The finalization process then pulls 
the entries from the list and calls the finalize method on it.

Cheers,
   - Andreas

Igor Stasenko wrote:
>  
> In recent topic on Seaside list, someone has asked, why Seasider's
> abandon the idea of using weak references (and use finalization
> technique when they die).
> The main issue was the slowness of weak finalization process
> implemented in Squeak.
> 
> The problem:
> - sometimes developer needs to get a notification from system when
> particular object become garbage, so an additional processing could be
> activated, called finalization.
> 
> How things currently working:
> 
> Squeak provides a default finalization scheme implemented by
> WeakRegistry class, where one could register a pair of weak reference
> and executor. Its connected with finalization process , which governed
> by WeakArray class.
> 
> Upon each GC, the finalization process awakes and sending
> #finalizeValues to all objects, registered in FinalizationDependents
> collection.
> When a WeakRegistry receives this message, it iterates over own
> WeakIdentityKeyDictionary instance to find a pairs, for which key
> (weak ref) became nil, and sends #finalize to the value (executor).
> 
> The problem with such approach, is a linear time consumption spent for
> scanning all registered key>value pairs.
> If you have thousands of objects registered in that way, while only
> few of them could become garbage, the finalization process still will
> spend a fair amount of time, trying to determine which ones became
> garbage.
> 
> To eliminate this waste, we need to implement a scheme in VM, which
> can help us to reach only those objects which is died during current
> GC cycle, leaving rest untouched.
> 
> Here is what i'd like to propose:
> 
> - add a special class
> 
> Object weakSubclass: #WeakReferenceWithNotification
> 	instanceVariableNames: 'list next'
> 	classVariableNames: ''
> 	poolDictionaries: ''
> 	category: 'Collections-Weak'
> 
> so, that VM can check this special kind of weak reference in
> ObjectMemory>>finalizeReference: method.
> 
> A 'list' ivar can point to any object, we only need to be sure it
> having at least one slot to hold a list head:
> 
> Object subclass: #FinalizationList
> 	instanceVariableNames: 'head'
> 	classVariableNames: ''
> 	poolDictionaries: ''
> 	category: 'Collections-Weak'
> 
> now, all we need is to modify #finalizeReference: method, to do
> following at the moment of storing nil pointer:
> 
> " this is not actually the slang code, just to illustrate what it does "
> 
> (oop class isKindOf: WeakReferenceWithNotification) ifTrue: [
>   | list |
>   list := oop at: ListSlotIndex.
>   oop at: NextSlotIndex put: (list at: HeadSlotIndex).
>   list at: HeadSlotIndex put: oop.
> ].
> 
> 
> What it does, it simply links given oop to the list.
> 
> And as you may suppose, if we have initial state:
> - list with head == nil
> - multiple instances with WeakReferenceWithNotification , all pointing
> to our list, and having a weak refs,
> 
> then after GC, if some of the refs become nilled, in a list's head we
> will have a list of weak references we need to finalize (or do
> anything else we want to).
> 
> Then a finalization process in case of WeakRegistry, don't needs to go
> through all weak references which are registered in itself, instead it
> could simply do:
> 
> "suppose we use a subclass "
> WeakReferenceWithNotification weakSubclass: #WeakReferenceWithExecutor
> 	instanceVariableNames: 'executor'
> 	classVariableNames: ''
> 	poolDictionaries: ''
> 	category: 'Collections-Weak'
> ...
> 
> ref := list head.
> ref notNil whileTrue: [
>    ref executor finalize.
>    ref := ref next.
> ].
> list head: nil.
> 
> P.S. Me hopes ;) , that i successfully shown that the actual changes
> to VM is quite simple and minimal. But effects of such change could
> have a major impact on a finalization scheme performance.
> 
> 


More information about the Vm-dev mailing list