Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What sort of memory leaks should I watch for with jQuery's data()?

Should I pair every data() call with a later removeData() call?

My assumptions: jQuery's remove() will remove elements from the DOM, and if I don't have any other references to remove, I don't have to do any more clean up.

However, if I have some javascript var or object referring to one of the elements being removed, I'll need to clean that up, and I'm assuming that applies to jQuery's data function, too, because it's referencing the elements somehow.

So if I do need to call removeData before remove, is there a shortcut to remove all data associated with an element or do I have to call each explicitly by name?

Edit: I looked through the source code and confirmed what Borgar and roosteronacid said. Remove takes the elements out of the dom and deletes any events and data stored with them - which is convenient, but makes me wonder when you would use removeData(). Probably not often.

like image 439
Keith Bentrup Avatar asked Jun 29 '09 00:06

Keith Bentrup


People also ask

What are memory leaks in JS?

What are memory leaks? In simple words, a memory leak is an allocated piece of memory that the JavaScript engine is unable to reclaim. The JavaScript engine allocates memory when you create objects and variables in your application, and it is smart enough to clear out the memory when you no longer need the objects.

What algorithm causes memory leak in JavaScript?

The setTimeout() and setInterval() are both methods of the HTML DOM Window object. Javascript timers are the most frequent cause of memory leaks as their use is quite common.


2 Answers

jQuery's data does not keep a reference to the element so that you don't need to worry about memory leaks. Its intended purpose is to solve this exact problem.

A slight simplification of how it works:

An id member is added to each "touched" DOM node. All subsequent actions involving that DOM element use that id.

var theNode = document.getElementById('examplenode');
theNode[ 'jQuery' + timestamp ] = someInternalNodeID;

You can access the id using the same function jQuery uses:

someInternalID = jQuery.data( document.body );

When you append data to the node it stores that on the jQuery object, filed under the node's internal id. Your $(element).data(key,value) translates internally to something like:

jQuery.cache[ someInternalNodeID ][ theKey ] = theValue;

Everything goes into the same structure, including event handlers:

jQuery.cache[ someInternalNodeID ][ 'events' ][ 'click' ] = theHandler;

When an element is removed, jQuery can therefore throw away all the data (and the event handlers) with one simple operation:

delete jQuery.cache[ someInternalNodeID ];

Theoretically, you may therefore also remove jQuery without leaks occurring from any references. jQuery even supports multiple separate instances of the library, each holding it's own set of data or events.

You can see John Resig explaining this stuff in the "The DOM Is a Mess" presentation.

like image 51
Borgar Avatar answered Sep 24 '22 00:09

Borgar


The whole point of jQuery is to abstract away from crappy JavaScript implementations and bugs in browsers.. such as memory leaks :)

.. Yup; all associated data to an element will be removed when that element is removed from the DOM.

like image 39
cllpse Avatar answered Sep 22 '22 00:09

cllpse