Concerns about weak refs and weak maps.

Hudson, Rick rick.hudson at
Thu Oct 28 17:41:41 PDT 2010

Hi Brendan,

I think we all agree that EcmaScript, the language, should not contain threads with shared memory constructs such as locks or transactions. We seem to disagree as to whether EcmaScript, the implementation, should be multithreaded. If bridge builders, compiler writers, GC implementations, need better (non-application visible) tools then running their tools concurrently seems the way forward. Web workers that share immutable heap object behind a message passing façade could provide reasonable performance without changing the (HTML5) standard. Optimizers running in a separate thread also seem like a good idea.  Moving the scans of weak maps into a stop the world GC only makes the GC more intrusive while removing the application writers ability to optimize their applications.

In the GC literature 50 milliseconds latency is considered the upper bound if one wishes to provide an acceptable client experience.  10 milliseconds is what one wants for a game experience. This is increasingly hard to achieve with a stop the world collector as the memory foot print grows while CPU speed does not.

In the long run I believe that EcmaScript will not be able to compete with other languages in providing highly responsive client side applications without a concurrent GC.

But to answer your direct question:
>> If you remove the concurrent GC concern, then what is your sense?
GC latency will increase as memory footprint and use of weak maps increases. Large application using weak maps will have performance bugs that will end up on the GC implementer's desk where they will be hard to diagnose and fix.

Perhaps if folks talk privately to the top half dozen Java GC implementers EcmaScipt might be able to avoid some of their pain.

-          Rick

From: Brendan Eich [mailto:brendan at]
Sent: Thursday, October 28, 2010 2:39 PM
To: Hudson, Rick
Cc: es-discuss; Andreas Gal
Subject: Re: Concerns about weak refs and weak maps.

On Oct 28, 2010, at 2:10 PM, Hudson, Rick wrote:

I have concerns about weak refs and weak maps, one concern related to usability, one related to performance bugs, and another other related to changing the complexity of the GC algorithm.

Hi Rick, your comments are on target, but I'll differ on some fine points below. Thanks for writing.

Weak maps act as a GC API and in doing so violate GC's greatest strength:  the user does not have to be concerned with memory management.  Since the user can never observe that a key/value pair has been deleted,  weak maps are much better than weak refs but they still seem capable of causing hard to diagnose and fix performance bugs related to memory pressure and the particular GC implementation.

This is all true, but developers are already concerned with memory management. GC is good, I like it, but it is not and never will be perfect (enough). Even V8 is facing criticism in its<> embedding, for among other things having too-small heap limits. Node users are retracing the JVM user footprints and asking for an explicit library call, gc(), to force collection.

So weakmaps can't be the breaking point that throws concern over memeory management via GC into users' faces. It's an issue on the client side too, already (and for many years, mostly due to cycles crossing through the DOM, which is under separate, often ref-counted, management, back to JS via the global object containing a closure capturing its environment, including document).

Plus, weakmaps give JS bridge-builders and compiler/runtime writers a needed tool, without which the only options are too costly (linear search of an array matching object reference identity) and leak-prone (strong references only).

 GC implementation
Software stacks on multicores will need GCs to become increasingly concurrent and latency free. Weak maps cause concurrent GCs and additional mutator synchronizations.  While a concurrent GC already has to do some synchronization, each additional synchronization point impedes scalability. My concern is that the number of synchronization points might be proportional to the number of <k, v> pairs in the weak maps (see below).

Browsers do not multithread JS, the language has no such execution model. More, it won't get one. Nodejs uses a single thread for all requests, requiring continuation passing style coding. There are alternatives, along Erlang lines, but they do not involve shared mutable state. So no global, concurrent GC is in the cards, on client or server -- my best projection (and strong advice!).

 GC Complexity
Another potential performance bug is that the complexity of the Abstract GC Algorithm at appears to be O(n**2), since each loop may only discover a single retained key k from (k,v) whose walk of the related value v discovers only a single unretained k. This would then be repeated and require rescanning all the weak maps in the each of the following iterations. Concurrent GCs would probable require one or more mutator synchronizations at each iteration.

Ignoring the concurrent GC concern, which I believe does not apply to JS because JS won't have threads and shared mutable state, you're right. Weak maps make GC potentially costly. Andreas Gal has an implementation in progress for Firefox and he can comment on this point.

 My sense is that the value of a simple efficient concurrent GC and reduced latency is higher than the value of weak maps so weak maps should not be part of the standard.

If you remove the concurrent GC concern, then what is your sense?


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list