[squeak-dev] Improving WeakKeyDictionary comment
leves at caesar.elte.hu
Sat May 28 11:25:02 UTC 2022
On Fri, 27 May 2022, Jakob Reschke wrote:
> Dear Squeakers,
> Whenever I read the class comment of WeakKeyDictionary, I know that I have to take care of something, but I do not know what. Can we improve the comment please to tell the readers more directly what is expected of them?
> - Must one ensure that #finalizeValues is sent to one's WeakKeyDictionary instance regularly?
Only if you are interested in finalization and want to do it your own way.
And even then, only if you want to have your finalizer executed as soon as
possible when a key of your dictionary has been garbage collected.
So, if you just want a dictionary with weak keys, the answer is no.
> - Should one register the dictionary instance via WeakArray addWeakDependent:?
Same as above. I'm not even sure it would work with
WeakKeyDictionaries. It's intended to work with WeakRegistries, which are
the main providers of finalization.
> - Which VM feature is the WeakRegistry class comment referring to; is it the semaphore used on the class side of WeakArray; and is it relevant to the use of WeakKeyDictionary?
One that has never really been used in Squeak and has been
obsoleted by ephemerons. Even though we do not use ephemerons for
> - If the answers to the questions above do not give it away, what must one do to use a WeakKeyDictionary safely?
The difference between a regular Dictionary and a WeakKeyDictionary is
that the latter cannot hold nil as a key, and your associations may
disappear when their keys are not referenced strongly.
> I volunteer to submit the results as comments in WeakKeyDictionary, WeakArray, and WeakRegistry to the Inbox.
> The following is just a transcript of the cynical voice in my head while trying to find some answers today. You do not need to read it. If you can answer the questions above, I would be more than happy. ;-)
> WeakKeyDictionary class comment:
> "I am a dictionary holding only weakly on my keys. This is a bit dangerous since at any time my keys can go away. Clients are responsible to register my instances by WeakArray such that the appropriate actions can be taken
> upon loss of any keys.
> See WeakRegistry for an example of use."
> So I look at WeakArray and WeakRegistry. WeakArray has only three methods, none of which seem to deal with garbage collection, finalization, or elements vanishing. On the class side there is #addWeakDependent:, which deals
> with class variables that have Finalization in their name. Is this what is meant by "register my instances by WeakArray"...? There is no method comment, so I do not know whether I should call that with my new
> WeakKeyDictionary or not, or what the effect would be. The class comment of WeakArray also does not tell me anything about finalization or registration.
> Looking at WeakRegistry, it associates the registered objects with an executor, and "When the object is garbage collected, the executor can take the appropriate action for any resources associated with the object." Not sure
> whether I need anything like this for my WeakKeyDictionary instance... It also says that it uses a "new VM feature" (the comment is from 2010), but does not say which one or how it works. In WeakRegistry, the
> 'valueDictionary' is a Weak(Identity)KeyDictionary. It is used in 10 methods, which takes some time to read. I can see that the dictionary stores WeakFinalizerItems, which holds the executors for an object. In
> #finalizeValues, the same is sent to the dictionary and to all objects in the 'executors' inst var, which is then set to nil. In the WeakKeyDictionary, #finalizeValues drops elements whose keys have become nil. Ah ha, so do I
> need to take care of sending #finalizeValues to my WeakKeyDictionary regularly...? In #installFinalizer a finalizer block is attached to the dictionary. This finalizer block adds its argument to the 'executors'. Taking a
> detour back to WeakKeyDictionary to find out when that block is evaluated... So when the dictionary receives #finalizeValues, fixes hash collisions, or grows, and notices keys that are gone, the values (WeakFinalizerItems)
> will be added to the 'executors', so that back in #finalizeValues of WeakRegistry, #finalizeValues will eventually be sent to all WeakFinalizerItems of garbage collected elements. But I still do not know what sends
> #finalizeValues to the WeakRegistry in the first place. The rest of the WeakRegistry methods do not seem to do anything fancy with the dictionary. Collision fixing or growing is unlikely to happen to the WeakKeyDictionary if
> it is not modified for a while, all the same while the keys may be garbage collected.
> For another chance, I read the class side methods of WeakRegistry. The #new constructor of WeakRegistry uses the previously discovered #addWeakDependent: method of WeakArray, hear hear. Reading further about the
> finalizationProcess in WeakArray, a FinalizationSemaphore is kept in the SpecialObjectsArray, which means that the VM is supposed to use this semaphore. The finalizationProcess sends #finalizeValues---bingo---to the
> dependents when the semaphore is signalled. Combining the clues I guess that this semaphore is singalled after the garbage collection has run. Is that the mysterious "new VM feature" to which the comment of WeakRegistry---at
> which I am not looking right now---was referring...? Since it is not spelled out in a comment, and since I am not willing to look at the VM sources now, my guess remains an assumption. Under this assumption, I could register
> my WeakKeyDictionary as a weak dependent in WeakArray class, so that after each GC #finalizeValues would be sent to my dictionary, which would clean up stale entries, which is likely the thing I was expected to care about.
> But maybe I missed another piece of the puzzle.
> Frankly, I do not wish to reverse engineer how the WeakRegistry works before I can use a WeakKeyDictionary. For that, the workings of WeakRegistry are not simple or well-described enough and it apparently needs some VM
> Kind regards,
More information about the Squeak-dev