<div dir="ltr"><div dir="ltr">Hi Levente,</div><br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Currently, the right thing to do is to use a WeakIdentityKeyDictionary<br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
and register a finalizer for each key (into the global WeakRegistry).<br>
Something like:<br>
<br>
m := Mutex new.<br>
w := WeakIdentityKeyDictionary new.<br>
1 to: 100 do: [ :onDemandInstVars |<br>
        | pseudoPackage |<br>
        pseudoPackage := Object new.<br>
        m critical: [ w at: pseudoPackage put: onDemandInstVars ].<br>
        pseudoPackage<br>
                toFinalizeSend: #cull: "Must be cull: to ignore the argument nil"<br>
                to: [ m critical: [ w finalizeValues ] ]<br>
                with: nil ].<br>
before := w array count: #notNil.<br>
Smalltalk garbageCollectMost.<br>
after := w array count: #notNil.<br>
{ before. after }<br></blockquote><div><br></div><div>Hmm.  For learning or for glory, and because you didn't put quotes around this being the right thing to do, I feel the need to challenge it.  :)</div><div><br></div><div>Unless I'm mistaken, this approach would mean finalizeValues will be called for every single element GC'd, which would be immensely wasteful.</div><div><br></div><div>Plus, having to register a finalizer for every key?  That seems overly burdensome just to use a WeakKeyDictionary.  It should "just work", but if it can't, the next best thing is to simply calling #finalizeValues manually.</div><div><br></div><div>    | w lastClean |<br>    w := WeakIdentityKeyDictionary new.<br>    1 to: 100 do: [ :onDemandInstVars |<br>        | pseudoPackage |<br>        pseudoPackage := Object new.<br>        w at: pseudoPackage put: onDemandInstVars ].</div><div><br></div><div>Done.  Then, somewhere in the application just put the following line at an appropriate place in the application.  Use the Time guard if necessary."</div><div><br></div><div>    (Time millisecondsSince: lastClean) > 30000 ifTrue: </div><div>       [ w finalizeValues. </div><div>       lastClean := Time millisecondClockValue ].<br></div><div><br></div><div>Simple.  Less code, fewer objects, less machine execution including no need for any Mutex serialization.<br></div><div><br></div><div>This is what I'd feel safe enough to call the "right thing to do", in quotes at least..  :)</div><div><br></div><div> - Chris</div></div></div>