You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jan 25, 2022. It is now read-only.
I have a definite use case for weak references in one of my projects, jsdom. It runs primarily in Node, but also in the browser. Of note, this case isn't related to resource management.
jsdom implements, among other things, the DOM Standard. In particular, there is one line that concerns us here: when removing a node:
For each NodeIterator object iterator whose root’s node document is node’s node document, run the NodeIterator pre-removing steps given node and iterator.
To correctly implement this step, you need a reference to every NodeIterator object that's ever been created, so you can update it correctly (by running the pre-removing steps).
This really requires weak references, as otherwise you end up holding a strong reference to every NodeIterator ever created, never releasing their memory, or the memory of the other objects that the NodeIterator references (e.g. the two DOM nodes it points to, root and reference node).
Of note:
This is not being used as any sort of backstop for cleaning things up. It's just plain required for correctness without massive memory leaks.
This doesn't require finalization at all.
What we really need is an "iterable weak set"; weak references of course can be used to build one of these (and an iterable weak set can be used to build a weak reference).
Finally, people may be amused by how we currently work around this. We have a user-configurable number, "max working NodeIterators", which we default to 10. We hold strong references to the last 10 created NodeIterators. If an 11th NodeIterator is created, we remove it from the list, then set an internal bit on it that says "sorry, this one's broken", and any methods you try to call on that NodeIterator will throw an exception, helpfully telling you to up the max working NodeIterators configuration.
We then loop over those 10 strongly-held NodeIterators whenever a node is removed from the document, and update them appropriately per the spec.