48

Can somebody explain in detail how Javascript engines deal with circular references ? Is there a big difference between browsers or even node.js ?

What I'm talking about is an explicit back-/next reference within objects. For instance:

var objA = {
    prop: "foo",
    next: null
};

var objB = {
    prop: "foo",
    prev: null
};

objA.next = objB;
objB.prev = objA;

There we go. If we do a console.log( objA ) we can see that we created an infinite chain. The big question is, is this bad ? Does it create memory leaks when not explicitly cleaned?

So do we have to

objA.next = null;
objB.prev = null;

or will the garbage collectors take care of us on constellations like this?

Phuc Thai
  • 718
  • 7
  • 17
jAndy
  • 231,737
  • 57
  • 305
  • 359

1 Answers1

73

Any half-decent garbage collector will handle cycles.

Cycles are only a problem if you do naive reference counting.

Most garbage collectors don't do ref-counting (both because it can't handle cycles, and because it's inefficient). Instead, they simply follow every reference they can find, starting from "roots" (typically globals and stack-based variables), and mark everything they can find as "reachable".

Then they simply reclaim all other memory.

Cycles are no problem because they just mean that the same node will be reached multiple times. After the first time, the node will be marked as "reachable" already, and so the GC will know that it's been there already, and skip the node.

Even more primitive GC's based on reference-counting typically implement algorithms to detect and break cycles.

In short, it's not something you have to worry about. I seem to recall that IE6's Javascript GC actually failed to handle cycles (I could be wrong, it's been a while since I read it, and it's been much, much longer since I touched IE6), but in any modern implementation, it is no problem.

The entire point in a garbage collector is to abstract away memory management. If you have to do this work yourself, your GC is broken.

See MDN for more information on modern garbage collection and the mark-and-sweep algorithms that are used.

Willem Mulder
  • 12,974
  • 3
  • 37
  • 62
jalf
  • 243,077
  • 51
  • 345
  • 550
  • 1
    What about http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Closures#Closures is it wrong? – Sandro Feb 06 '13 at 08:53
  • 2
    @Sandro read my answer again. :) A sane GC handles cycles just fine. Everything that is newer than IE6 can be considered sane. If you need to support IE6 then you have to worry about its broken handling of cycles. Apparently, Google's guide is written under the assumption that such broken browsers have to be supported, so they have to jump through some additional hoops. – jalf Feb 06 '13 at 09:36
  • @Sandro There is something special going on in that example: a DOM element is one part of the circular reference. Generally, you'd leak memory until you close the page. If I recall correctly, however, IE doesn't always remove references to the DOM when you navigate away. (Apparently doing that broke some pages?) – Carl Walsh Dec 03 '13 at 16:03
  • 2
    Douglas Crockford [mentions](http://javascript.crockford.com/memory/leak.html) this [IE6 flaw](http://support.microsoft.com/kb/929874/), too. I think nowadays we can consider it irrelevant to most web applications. – mknecht Oct 03 '14 at 18:25