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

T.J. Crowder tj.crowder at farsightsoftware.com
Thu Mar 30 08:45:04 UTC 2017


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> 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
>
> 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> 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
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
>
> _______________________________________________
> es-discuss mailing listes-discuss at mozilla.orghttps://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 <+41%2056%20250%2040%2002>
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170330/9fd2c190/attachment-0001.html>


More information about the es-discuss mailing list