2

I have several instances where my Javascript code appears to be leaking memory but I'm not sure what I should be expecting from the garbage collector.

For example var = new Object() in an interval timer function running in Firefox seems to leak over time. There's some simple solutions but I'm curious if I should be expecting the garbage collector to handle everything or I'm responsible for helping the garbage collector.

If I need to help the garbage collector what are the rules?

Fabrício Matté
  • 69,329
  • 26
  • 129
  • 166

2 Answers2

0

Most (I believe all) Javascript (ECMAScript) engines work by a method called "reference counting." I'll leave you to goggle that term.

In short, an object is freed for release when nothing is pointing to it ... using it.

Two things may throwing off your sense of how much memory is being used.

1) ECMAScript does not release the object the instant that the system is done with it. Garbage collection is run "as needed." This can vary widely.

2) Closures can hold onto a reference longer than you think. Accidental closures can hold things longer than you might expect.

Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74
  • Do you know what would happen in the case where the var is re-assigned such as while(1) var = new Object(); – David Broadhurst Aug 26 '12 at 01:52
  • In the case of something like `var a; while(true) { a = {}; // Better than new object }` In that particular code, an object will be created, then freed for release in the next loop iteration. The GC will run when needed, but there is no memory leak. – Jeremy J Starcher Aug 26 '12 at 02:08
  • So in this case the variable doesn't go out of scope but it still gets garbage collected, which makes sense but I havent seen this case explained by any descriptions of how GC works or am I just missing this part of the algorithm? BTW - This isn't just theoretical. I have JS code that's leaking and I'm suspicious of multiple var a = new object() within recursive code that's running on a timer. I could change the code but its more convient the way it currently working. – David Broadhurst Aug 26 '12 at 02:22
0

Had to make this an answer rather than a comment for length:

OK -- first a clarification of terms:

If it is running on a timer, then it is not recursive. It is a common misunderstanding, however.

It recursive code, a function calls itself -- the original function invocation remains on the stack until the whole thing finally unwinds and a value is returned to the original caller. When using a time out, each iteration of the function its in a separate execution context.

Recursive function example function factorial(n) { if (n == 1) { return 1; } else { return n * factorial(n-1); } }

This is /not/ recursive: function annoy() { window.setTimeout(annoy, 1000); window.alert("This will annoy every second!"); }

Each iteration of 'annoy' is completely independent and stand alone. It just sets up the timer for another instance to be called. There is no pile of 'annoy' functions on the stack and you can't return anything to the caller.

Secondly: In the example that I gave you, the variable a not go out out of scope, but the old objects that a refers to had no active references so they are free for release. What a variable points to can vary.

var a, b;
a = {};
b = a;   // This object now has TWO references using it.

b = null;  // The object now has one reference
a = null;  // Object has no references and is free for release.

At this point, the best thing I can do is point you here:

http://www.ibm.com/developerworks/web/library/wa-sieve/

Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74