A WeakMap where values (not keys) are weak references?

Michael Kriegel michael.kriegel at actifsource.com
Thu Mar 30 09:09:14 UTC 2017


Totally agree. WeakRef is what we want and WeakValueMap is what I want 
to build with it. Sugar would be if the standard provides "an 
out-of-the-box WeakValueMap *as well*".

Automatic removal of entries after they became obsolete would be 
necessary - be it integrated or via a callback mechanism (i guess the 
executor is sth. like that.)


On 30.03.2017 10:45, T.J. Crowder wrote:
> Right -- but it's really weak references you're after, right? Because 
> with weak references, a Map can be a WeakValueMap, but other 
> structures are also possible. With that proposal's `executor` feature, 
> the map can even be proactive removing entries for objects that have 
> become only weakly reachable.
>
> I'd like to see weak references (perhaps not quite that exact 
> proposal, but along those lines), not just a WeakValueMap. I've only 
> needed them rarely (your example is a good one), but when I've needed 
> them, they were pretty much the only option... I don't mind an 
> out-of-the-box WeakValueMap *as well*, I just don't want it *instead*.
>
> -- T.J. Crowder
>
> On Thu, Mar 30, 2017 at 9:21 AM, Michael Kriegel 
> <michael.kriegel at actifsource.com 
> <mailto:michael.kriegel at actifsource.com>> wrote:
>
>     I am also still very interested in Weak references / a weak map,
>     where the values are held weakly. Here is my example: I want to
>     easily build caches, which lose their values, when there are no
>     other references to them. Example pseudo code (assuming server
>     request answers synchronously for simplicity):
>
>     var Cache = new WeakValueMap();
>
>     function request(Key) {
>
>         var CachedResult = Cache.get(Key);
>
>         if (CachedResult) return CachedResult;
>
>         var UnprocessedResult = doServerRequest(Key);
>
>         var BigProcessedObject =
>     doVeryHeavyComputingTask(UnprocessedResult);
>
>         Cache.set(Key,BigProcessedObject);
>
>         return BigProcessedObject;
>
>     }
>
>     Thoughts:
>
>     - doHeavyComputingTask takes a long time, so it should be done
>     only once per key (until it is uncached)
>
>     - BigProcessedObject is really big, it shall be in memory at most
>     once at any time
>
>     - When the last reference to a BigProcessedObject is lost, it
>     shall be removed from cache to save memory
>
>     - removal could be delayed by holding a reference to a
>     BigProcessedObject and releasing it using a setTimeout-Timer.
>
>     Without WeakValueMap I have to build my own reference counting, so
>     everyone who requests the object for a Key has to "unrequest" it
>     again, else it would provoke a memory leak. This implies, that the
>     life cycle of an object is tracked, so each object, which has a
>     reference to a BigProcessedObject needs something like a
>     destructor. As there is no destructor in JS you have to write a
>     method and manually call it. Thus each object needs to have a
>     single known owner or reference counting/tracking has to be done
>     for that object, too. This propagates through your whole program.
>     Finally as a developer you end up building your own garbage
>     collector, which:
>
>     - is error prone
>
>     - consumes extra memory, as there are already all structures
>     present for garbage collecting in the JS engine, just it is not usable
>
>     - takes up lots of time for development and debugging
>
>     So it is a/the classical example case for
>     https://github.com/tc39/proposal-weakrefs
>     <https://github.com/tc39/proposal-weakrefs>
>
>
>     On 21.03.2017 08:34, T.J. Crowder wrote:
>>     What are your use cases for it?
>>
>>     Rather than tying it to being a `Map`, I'd prefer to see
>>     something like Java's [`WeakReference`][1]:  You could store the
>>     `WeakReference`s in a `Map` if you wanted strongly-referenced
>>     keys with weakly-referenced values.
>>
>>     -- T.J. Crowder
>>
>>     [1]:
>>     http://docs.oracle.com/javase/8/docs/api/java/lang/ref/WeakReference.html
>>     <http://docs.oracle.com/javase/8/docs/api/java/lang/ref/WeakReference.html>
>>
>>     On Tue, Mar 21, 2017 at 6:15 AM, /#!/JoePea <joe at trusktr.io
>>     <mailto:joe at trusktr.io>> wrote:
>>
>>         Hey all,
>>
>>         I'd like to have something like a WeakMap where the keys can
>>         be primitives and the values are weakly-held Objects, so if
>>         there are no more references to any of the Object values that
>>         the entry gets removed from the map.
>>
>>         For example, it might look like this:
>>
>>         ```
>>         {
>>         ["foo"] => SomeObject,
>>         ["
>>         ​bar​
>>         "] =>
>>         ​OtherObject​
>>         ,
>>         }
>>         ```
>>
>>         where if there are no more references to `OtherObject`, then
>>         `['bar'] => OtherObject` is removed from the map.
>>
>>         Usage would be very similar to WeakMap, like
>>
>>         ```
>>         let m = new ReversedWeakMap
>>
>>         m.add('foo', SomeObject)
>>         m.add('
>>         ​bar​
>>         ',
>>         ​OtherObject​
>>         )
>>         ​console.log(m.get('bar')) // OtherObject
>>
>>         ... time passes, no more references to OtherObject,
>>         OtherObject is collected ...
>>
>>         console.log(m.get('bar'))​ // undefined
>>
>>         ```
>>
>>         I thought of using WeakMap values as keys, and vice versa,
>>         but it seems to be impossible.
>>
>>         I guess maybe it is difficult to add this natively because it
>>         would mean that GC needs to be completely deterministic as
>>         far as JS programs go. For example:
>>
>>         ```js
>>         let m = new ReversedWeakMap
>>
>>         function main() {
>>         m.set('foo', {})
>>         console.log(m.get('foo')) // {}
>>         }()
>>
>>         main()
>>
>>         // GC would have to be guaranteed to have happened at this point.
>>
>>         console.log(m.get('foo')) // undefined
>>
>>         ```
>>
>>
>>         */#/!//*JoePea
>>
>>         _______________________________________________
>>         es-discuss mailing list
>>         es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>>         https://mail.mozilla.org/listinfo/es-discuss
>>         <https://mail.mozilla.org/listinfo/es-discuss>
>>
>>
>>
>>
>>     _______________________________________________
>>     es-discuss mailing list
>>     es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>>     https://mail.mozilla.org/listinfo/es-discuss
>>     <https://mail.mozilla.org/listinfo/es-discuss>
>
>     -- 
>     Michael Kriegel • Head of R&D • Actifsource AG • Haldenstrasse 1 • CH-6340 Baar •www.actifsource.com <http://www.actifsource.com>  •+41 56 250 40 02 <tel:+41%2056%20250%2040%2002>
>
>     _______________________________________________ es-discuss mailing
>     list es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>     https://mail.mozilla.org/listinfo/es-discuss
>     <https://mail.mozilla.org/listinfo/es-discuss> 
>
-- 
Michael Kriegel • Head of R&D • Actifsource AG • Haldenstrasse 1 • CH-6340 Baar • www.actifsource.com • +41 56 250 40 02
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170330/e1ed660e/attachment-0001.html>


More information about the es-discuss mailing list