2

If I do something like

// global scope
function stuff() {
    // local scope
    var a = new SomeHugeMemoryHog();
}

// a doesn't exist down here, but what happened to the memory from the "stuff" scope?

Will I create a memory leak if I don't set a = null at the end of the stuff scope? Or should I not worry about it? I'm asking this question with emphasis on creating DOM objects (such as a canvas) inside the scope of functions (which I don't use later at any time). I'm only using the canvas to grab vector dimensions.

Jacksonkr
  • 31,583
  • 39
  • 180
  • 284

4 Answers4

3

No, it should get garbage collected once there are no more references to it.

Kevin Ennis
  • 14,226
  • 2
  • 43
  • 44
3

As others have pointed out that since there is no reference to a outside the function the garbage collector will collect it, most likely on the next collection.

Some things you need to watch out for, however, is indirect capture. A common place this happens is in event handlers through closure capture. For example,

function stuff() {
    var a = new SomeLargeObject();
    $("#somediv").click(function () { /* something */ });
}

Even if the nested function doesn't use a. a might be kept alive because the activation record of stuff is still alive. Also, DOM objects might be collected differently than normal JavaScript objects which might cause them to be susceptible circular referneces causing collection problems. This most problematic in older browsers and since you reference using a canvas browsers that support canvas tend to be more modern and correctly handle circular references as well as allowing local variables not captured by a closure to collect.

chuckj
  • 27,773
  • 7
  • 53
  • 49
  • Do modern browsers also blindly cling to everything in scope or can they separate the variables that are still being used from those that aren't? The OP mentioned canvas elements so I think we can assume this is not IE6 :) – hugomg Dec 05 '11 at 01:56
  • Modern JavaScript engines will not keep unreferenced variables alive unless the state is observable such as if eval() is called. I clarified my answer. – chuckj Dec 05 '11 at 09:19
1

You shouldn't worry about it. a will be a local global within the stuff() function (and visible to any code that runs "lower", but will not visible outside of the stuff() call.

e.g.

<script>
// a does not exist here

function stuff() {
   // no a here
   var a = new SomeHugeMemoryHog(); // a will be set once SomeHugeMemoryHog is created and the constructor returns
   // a exists here
}

// no a here either

stuff(); // a exists while stuff is running

// a has gone out of scope and will be cleaned up.

</script>
Marc B
  • 356,200
  • 43
  • 426
  • 500
-1

The only case I can see a possible memory leak is when your function is actually used as a constructor. i.e.

var someObj = new stuff();

Otherwise, the variable a will get garbage collected.

shinkou
  • 5,138
  • 1
  • 22
  • 32
  • This is not true. Since the object is not assigned to `this` still no reference exists to the object create by `new SomeHugMemoryHog()`. – chuckj Dec 05 '11 at 01:11
  • @chuckj You should give [this](http://mckoss.com/jscript/object.htm) a read and make sure you check out the **Private Members** section. – shinkou Dec 05 '11 at 02:51
  • "Private members" imply closures. Nothing in the `stuff` function resembles one, be it called as a constructor or not. – katspaugh Dec 05 '11 at 07:34
  • @shinkou I understand closures as I pointed out in my answer. Your answer implies the code in the question, unmodified, would leak if called with `new`. That is not true. If it was modified by adding a closure, such as is mentioned in the article you referenced, then `a` could be captured. – chuckj Dec 05 '11 at 08:48