Static News Archive

   (1-Mar-09 18:58)  Javascript Memory leaks, and avoiding them
Memory leaks - they are something that a javascript programmer may not think they have to contend with, when in actual fact, they are a very real problem.

In my experience, Internet explorer seems to be the biggest offender, however other browsers can be made to leak memory as well.

These examples of how to make your javascript leak work in IE7.0 (and probably other versions).

-- Problem 1--
Circular references.
So, we have an object, and we have a property on that object. Now we assign that property back to the object itself. Bam - memory leak.
A more realistic example is perhaps where we have object 1, then we have a property in that object which points to object 2. Now, add a property to object 2, which points back to object 1::

for (var i = 0; i < 10000; i  ) {
var myDiv = document.createElement('div');
var myDiv2 = document.createElement('div');

myDiv.expandoProperty = myDiv2;
myDiv2.expandoProperty = myDiv;

-- Solution--
Nullify your properties.
When you are done with your crazy web of circular property references, simply nullify the properties:
    myDiv.expandoProperty = null;
myDiv2.expandoProperty = null;

-- Problem 2--
Anonymous inner functions.
Well - it's not so much the inner function that's the problem, but the memory you allocate in the external function....
So say you have a function which has a load of memory it allocates for arrays and things. Now, when we exit the scope of that function, we'd expect the memory to be marked for garbage collection.

But now, let's say we have an anonymous inner function in that function. The function doesn't have to do anything, but the very fact that it has access to the local variables in it's enclosing function means that those variables cannot be cleaned up.

function SetupLeak()
var myDiv = document.getElementById('LeakedDiv');
var myVar = null;
// allocate loads of memory
myVar = new Array(1000).join(new Array(2000).join("XXXXX"));
// inner function means our memory will not be able to be cleaned up
myDiv.onclick = function() { };

-- Solution--
Declare large variables outside the scope of the function.
By declaring our large myVar array variable external to the SetupLeak function, we can later on nullify it when we are done. This will cause the memory to be cleaned up the next time the GC makes its rounds.

-- Additional--

When making this, I found it useful to have a function which would cause the garbage collector in IE to fire, and go and cleanup stuff it didn't need allocated anymore.
Interestingly, allocating 32k of memory seems to do the trick:
function FireCleanup() {
var myArray = new Array;
for (var i = 0; i < 8192; i ) {
myArray[i] = i;

Post a comment     
(10-Jan-10 16:56)  Posted by olivvv
interesting post !
to trigger the garbage collector in EI you can simply use garbageCollect()

<-  (8-Feb-09 15:03)  Using Assembly Resol... (5-Mar-09 14:54)  Javascript inheritan...  ->