Igor,<div><br></div><div>    read up on ephemerons.  They&#39;re a fine way of doing instance-based finalization in Smalltalk, designed originally by George Boswith and implemented in Digitalk&#39;s Smalltalk.  They&#39;re &quot;smart&quot; associations which get queued for finalization when the only references to their key are through ephemerons.  They&#39;ve been in the VW VM since I implemented them in about 2000, and they&#39;re actually being used up in the image now.<br>
<br><div class="gmail_quote">On Wed, Apr 22, 2009 at 3:19 PM, Igor Stasenko <span dir="ltr">&lt;<a href="mailto:siguctua@gmail.com">siguctua@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
In recent topic on Seaside list, someone has asked, why Seasider&#39;s<br>
abandon the idea of using weak references (and use finalization<br>
technique when they die).<br>
The main issue was the slowness of weak finalization process<br>
implemented in Squeak.<br>
<br>
The problem:<br>
- sometimes developer needs to get a notification from system when<br>
particular object become garbage, so an additional processing could be<br>
activated, called finalization.<br>
<br>
How things currently working:<br>
<br>
Squeak provides a default finalization scheme implemented by<br>
WeakRegistry class, where one could register a pair of weak reference<br>
and executor. Its connected with finalization process , which governed<br>
by WeakArray class.<br>
<br>
Upon each GC, the finalization process awakes and sending<br>
#finalizeValues to all objects, registered in FinalizationDependents<br>
collection.<br>
When a WeakRegistry receives this message, it iterates over own<br>
WeakIdentityKeyDictionary instance to find a pairs, for which key<br>
(weak ref) became nil, and sends #finalize to the value (executor).<br>
<br>
The problem with such approach, is a linear time consumption spent for<br>
scanning all registered key&gt;value pairs.<br>
If you have thousands of objects registered in that way, while only<br>
few of them could become garbage, the finalization process still will<br>
spend a fair amount of time, trying to determine which ones became<br>
garbage.<br>
<br>
To eliminate this waste, we need to implement a scheme in VM, which<br>
can help us to reach only those objects which is died during current<br>
GC cycle, leaving rest untouched.<br>
<br>
Here is what i&#39;d like to propose:<br>
<br>
- add a special class<br>
<br>
Object weakSubclass: #WeakReferenceWithNotification<br>
        instanceVariableNames: &#39;list next&#39;<br>
        classVariableNames: &#39;&#39;<br>
        poolDictionaries: &#39;&#39;<br>
        category: &#39;Collections-Weak&#39;<br>
<br>
so, that VM can check this special kind of weak reference in<br>
ObjectMemory&gt;&gt;finalizeReference: method.<br>
<br>
A &#39;list&#39; ivar can point to any object, we only need to be sure it<br>
having at least one slot to hold a list head:<br>
<br>
Object subclass: #FinalizationList<br>
        instanceVariableNames: &#39;head&#39;<br>
        classVariableNames: &#39;&#39;<br>
        poolDictionaries: &#39;&#39;<br>
        category: &#39;Collections-Weak&#39;<br>
<br>
now, all we need is to modify #finalizeReference: method, to do<br>
following at the moment of storing nil pointer:<br>
<br>
&quot; this is not actually the slang code, just to illustrate what it does &quot;<br>
<br>
(oop class isKindOf: WeakReferenceWithNotification) ifTrue: [<br>
  | list |<br>
  list := oop at: ListSlotIndex.<br>
  oop at: NextSlotIndex put: (list at: HeadSlotIndex).<br>
  list at: HeadSlotIndex put: oop.<br>
].<br>
<br>
<br>
What it does, it simply links given oop to the list.<br>
<br>
And as you may suppose, if we have initial state:<br>
- list with head == nil<br>
- multiple instances with WeakReferenceWithNotification , all pointing<br>
to our list, and having a weak refs,<br>
<br>
then after GC, if some of the refs become nilled, in a list&#39;s head we<br>
will have a list of weak references we need to finalize (or do<br>
anything else we want to).<br>
<br>
Then a finalization process in case of WeakRegistry, don&#39;t needs to go<br>
through all weak references which are registered in itself, instead it<br>
could simply do:<br>
<br>
&quot;suppose we use a subclass &quot;<br>
WeakReferenceWithNotification weakSubclass: #WeakReferenceWithExecutor<br>
        instanceVariableNames: &#39;executor&#39;<br>
        classVariableNames: &#39;&#39;<br>
        poolDictionaries: &#39;&#39;<br>
        category: &#39;Collections-Weak&#39;<br>
...<br>
<br>
ref := list head.<br>
ref notNil whileTrue: [<br>
   ref executor finalize.<br>
   ref := ref next.<br>
].<br>
list head: nil.<br>
<br>
P.S. Me hopes ;) , that i successfully shown that the actual changes<br>
to VM is quite simple and minimal. But effects of such change could<br>
have a major impact on a finalization scheme performance.<br>
<font color="#888888"><br>
<br>
--<br>
Best regards,<br>
Igor Stasenko AKA sig.<br>
</font></blockquote></div><br></div>