What is the status of Weak References?

Kevin Gadd kevin.gadd at gmail.com
Sat Feb 2 13:17:34 PST 2013


> 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.

I agree that there are scenarios where .dispose() or a similar
protocol may be come necessary; in those scenarios it would be great
if JS had some mechanism that could be used to simplify the proper use
of the protocol. Given that the need for Weak References in many
scenarios would be reduced because a partially (or wholly) automatic
implementation of that protocol can make it much easier to use the
protocol correctly. As I mentioned earlier, I think 'using' in C# is a
relatively simple feature that lets you express this, and function
scoped values with destructors like in C++ are a great way to express
this since you can increment a refcount in the constructor and
decrement it in the destructor. The downsides still remain, though -
refcounting (or other forms of non-GC management) add some overhead to
all the code that uses objects managed with those lifetime policies.
Manual refcounting requires the programmer to think about every
function to understand where refs should be added/removed and adds
noise to the code; explicit .dispose() without refcounting requires a
programmer to have a global understanding of his/her application in
order to determine the correct location to call it, which is very
difficult for large applications.

> 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.

The return value is a strong reference because otherwise you'd have to
write a check on every line to see if the object had expired in
between statements. It'd also mean that any function you passed the
weak object to would have to perform the check.

You can think of a weak reference as similar mechanically to a
refcounted object: You 'acquire' a reference to the object, hold onto
it a while to use the object, then 'release' the reference. In
refcounting this is done with ++/-- to prevent destruction; for weak
references, you do this by converting the WR temporarily into a strong
reference and then discarding it.

-kg


More information about the es-discuss mailing list