[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