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

Michael Kriegel michael.kriegel at actifsource.com
Thu Mar 30 08:21:44 UTC 2017


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


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
>
> 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
> 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/10b5c3f5/attachment-0001.html>


More information about the es-discuss mailing list