Precise explanation of JavaScript <-> DOM circular reference issue
Posted
by
Joey Adams
on Stack Overflow
See other posts from Stack Overflow
or by Joey Adams
Published on 2012-04-10T16:25:09Z
Indexed on
2012/04/10
17:29 UTC
Read the original article
Hit count: 254
One of the touted advantages of jQuery.data versus raw expando properties (arbitrary attributes you can assign to DOM nodes) is that jQuery.data is "safe from circular references and therefore free from memory leaks". An article from Google titled "Optimizing JavaScript code" goes into more detail:
The most common memory leaks for web applications involve circular references between the JavaScript script engine and the browsers' C++ objects' implementing the DOM (e.g. between the JavaScript script engine and Internet Explorer's COM infrastructure, or between the JavaScript engine and Firefox XPCOM infrastructure).
It lists two examples of circular reference patterns:
DOM element → event handler → closure scope → DOM
DOM element → via expando → intermediary object → DOM element
However, if a reference cycle between a DOM node and a JavaScript object produces a memory leak, doesn't this mean that any non-trivial event handler (e.g. onclick
) will produce such a leak? I don't see how it's even possible for an event handler to avoid a reference cycle, because the way I see it:
The DOM element references the event handler.
The event handler references the DOM (either directly or indirectly). In any case, it's almost impossible to avoid referencing
window
in any interesting event handler, short of writing asetInterval
loop that reads actions from a global queue.
Can someone provide a precise explanation of the JavaScript ↔ DOM circular reference problem? Things I'd like clarified:
What browsers are effected? A comment in the jQuery source specifically mentions IE6-7, but the Google article suggests Firefox is also affected.
Are expando properties and event handlers somehow different concerning memory leaks? Or are both of these code snippets susceptible to the same kind of memory leak?
// Create an expando that references to its own element. var elem = document.getElementById('foo'); elem.myself = elem; // Create an event handler that references its own element. var elem = document.getElementById('foo'); elem.onclick = function() { elem.style.display = 'none'; };
If a page leaks memory due to a circular reference, does the leak persist until the entire browser application is closed, or is the memory freed when the window/tab is closed?
© Stack Overflow or respective owner