What is the status of Weak References?

David Bruant bruant.d at gmail.com
Sat Feb 2 05:19:51 PST 2013


Le 02/02/2013 06:41, Nathan Wall a écrit :
> David Bruant wrote:
> > >> David Bruant wrote:
> > >> Garbage collectors have evolved and cycles aren't an issue any 
> longer, weak
> > >> references or not.
> > >
> > > Kevin Gadd wrote:
> > > Cycles are absolutely an issue, specifically because JS applications
> > > can interact with systems that are not wholly managed by the garbage
> > > collector. The problem in this case is a cycle being broken *too
> > > early* because the application author has to manually break cycles. To
> > > present a couple simple examples:
> > >
> > > I have a top-level application object that manages lower-level 'mode'
> > > objects representing screens in the application. The screens, when
> > > constructed, attach event listeners to the application object. Because
> > > the application manages modes, it needs to have a list of all the
> > > active modes.
> > > * The event handler closures can accidentally (or intentionally)
> >
> > Last I heard, it's very difficult to accidentally capture a 
> reference in
> > a closure because modern engines check which objects are actually used
> > (looking at variable names), so for an object to be captured in a
> > closure, it has to be used. So "intentionally".
>
> We had a situation recently where we needed to monitor an element with 
> `setInterval` to get information about when it was resized or moved. 
>  As library authors we wanted to encapsulate this logic into the 
> module so that it would "just work".  We wanted someone to be able to 
> call `var widget = new Widget();`, attach it to the document, and have 
> it automatically size itself based on certain criteria. If a developer 
> then moved its position in the document (using purely DOM means), we 
> wanted it to resize itself automatically again. We didn't want to make 
> a requirement to call a public `resize` method, nor did we want to 
> impose `dispose` (it's an easy thing to forget to call and it doesn't 
> feel like JavaScript).  Of course, strongly referencing the element in 
> the `setInterval` keeps it alive in memory even after the developer 
> using the library has long since discarded it.
Since we're discussing the addition of a new feature, let's first start 
to see how existing or about-to-exist features can help us solve the 
same problem.

In an ES6 world, new Widget() can return a proxy and you, as the widget 
library author, can track down anytime the element is moved and resized 
(the handler will probably have to do some unwrapping, function binding, 
etc, but that's doable).
DOM mutation observers [1] can be of some help to track down this, I think.

Hmm... It's been a couple of years that I have the intuition that events 
should be considered as part of an object interface and not some sort of 
external thing and I think the justification is right here.
Doing setInterval polling has you do forces you to create a function 
unrelated to the object you want to observe and keeps a reference in 
that function.
If you were able to attach an event listener to the object itself to be 
notified of just what you need, the observer function would die as soon 
as the object it's attached to would die.

In your particular case, events at the object level would solve your 
problem, I think.


[answering separately]
> nor did we want to impose `dispose` (it's an easy thing to forget to 
> call and it doesn't feel like JavaScript)
I'd like to repeat something I wrote in another message: "...a very 
important point that most developers ignore or forget. GC is an 
undecidable problem, meaning that there will always be cases where a 
human being needs to figure out when in the object lifecycle it is not 
longer needed and either free it in languages where that's possible or 
make it collectable in languages with a GC. There will be such cases 
even in languages where there are weak references. "
And when such a case will be found, what will be the solution? Adding a 
new subtler language construct which exposes a bit more of the GC?

JavaScript has an history of being the language of the client side where 
a web page lives for a couple of minutes; leaks were largely 
unnoticeable because navigating or closing a tab would make the content 
collectable (well... except in crappy version of IE in which JS content 
could make browser-wide leaks -_-#).
As soon as we have long-running JavaScript, we have to start caring more 
about our memory usage, we have to question what we assumed/knew of 
JavaScript. The GC does maybe 80-100% of the job in well-written complex 
code, but we must never forget that the GC only does an approximation of 
an undecidable problem.
In applications where memory matters a lot, maybe a protocol like 
.dispose will become necessary.


> In this case, we managed to come up with a solution to refer to 
> elements "weakly" through selectors, retrieving them out of the 
> document only when they're attached (we have a single `setInterval` 
> that always runs, but it allows objects to be GC'd).  However, this 
> solution is far from fool-proof, lacks integrity (any element can 
> mimic our selectors and cause us grief), and not performant.  In our 
> case it's good enough, but I can imagine a case where it wouldn't be. 
>  I can also imagine a case where you wouldn't have the luxury to use 
> DOM traversal as a "weak" mechanism for referring to objects.  I think 
> it could be useful internally in library components which make use of 
> 3rd party components (in this case the DOM) to be able to monitor 
> aspects of those components only when they're being consumed.
Do you mean events? :-)

> Having said that, I also understand the desire to keep the language 
> deterministic and to not expose GC operations.
About weakrefs, I've read a little bit [2][3] and I'm puzzled by one 
thing: the return value of get is a strong reference, so if a 
misbehaving component keeps this strong reference around, having passed 
a weak reference was pointless.

David

[1] https://developer.mozilla.org/en-US/docs/DOM/MutationObserver
[2] http://wiki.ecmascript.org/doku.php?id=strawman:weak_references
[3] http://weblogs.java.net/blog/2006/05/04/understanding-weak-references
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130202/303f0fd3/attachment.html>


More information about the es-discuss mailing list