1

I have some troubles with memory leaks in JavaScript.

I'm using the Leak Memory 0.4.5 extension for Firefox which shows me those JavaScript objects which still remain in the memory.

Now I'm not sure how to correctly unbind dom-object from events etc.

For instance, I have a jQuery-widget called 'dropdownbox'. In the destroy method I make all the necessary stuff to unbind event-handlers like:

this.box.find('.toggler').unbind();
this.box.remove();
this.box = null;

These 3 lines are a must, or is it possible to call only this.box.remove()?

Till today I never have unbound or cleared something from DOM elements because I thought it doesn't matter. But I came up with the problem, that after 2 hours of developing on the same site, my Firefox consumes 1GB!

So I read a bit of memory leaks when using closures etc.
So that's my second question: I use very often closures because they are really cool and handy.
Some people say that you shouldn't use closures for everything. so for example if we have the following code:

function foo(param1, param2) {
  var local1, local2;
  $('a').click(function() {
    alert('YEAH');
  });
}

It would be better to do it like:

funtion foo(param1, param2) {
      var local1, local2;
      $('a').click(clickEvent);
    }
function() {
  alert('YEAH');
}

Or have I misunderstood that?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Davincho
  • 121
  • 1
  • 7

2 Answers2

3

I know this is an old topic, but You have mentioned closures yet the examples you have provided are not closures. Closure "happens" when a function returns the inner function. People will probably look here because this question is on top of google search results for "javascript memory leaks unbind events" and they should not be given the wrong information :) I know it was not intentional.

Please look here for an excellent closures explanation: How do JavaScript closures work?

Community
  • 1
  • 1
op1ekun
  • 1,918
  • 19
  • 26
1

You can just call:

this.box.remove();
this.box = null;

.remove() will also remove any child elements and their event handlers/data as well. Nulling out the reference held by .box to the element is the last step for complete removal (assuming nothing else it hanging onto it).

For your other example, the second version is a bit more efficient since the handler's not copied all over the place, the bigger that handler is the more it makes a difference.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • ok so i have to call $(window).unload(function() { $('temp').mywidget('destroy') }); to clean all correctly? – Davincho Sep 25 '10 at 17:35
  • @Davincho - You can, though most garbage collectors will cleanup when leaving the page (older IE you need to check but that's it). It's important to cleanup everything possible in your `destroy` function though, so any manual destroys are complete. – Nick Craver Sep 25 '10 at 17:42
  • that's the point: the garbage collector won't cleanup an object when we have circular references, so is there other posibility than call the destroy-method when the pages get unloaded? – Davincho Sep 25 '10 at 17:47
  • @Davincho - What circular references do you have? Event handlers and data aren't referenced by the DOM element, only it's `$.expando` property is there, not a direct reference, just a unique ID. If you can, you want to avoid creating circular references at all, like the jQuery event system does by default. – Nick Craver Sep 25 '10 at 17:53