0

Javascript memory leaks: What to do in a nutshell

>For one of my company‘s customers, we have been wrestling with a memory leak in one of the javascript heavy pages in their application. The main purpose of this blog entry is to provide a memento for the team working on that product, about what to be careful about when writing javascript.

The problem:

Note that this post gives a simplified overview of what goes on in a browser.

When a browser interprets a javascript code, it uses a garbage collector (GC) to reclaim memory that is no longer being referenced. In addition to the javascript GC, browsers also have a separate garbage collector for DOM objects in the displayed web pages. These two GCs work together to allow the browser to safely forget objects.

For finding out whether an object in memory is in use or not, GCs maintain the number of references to each object. When they detect that an object don’t have any references, they remove it from memory. If the removed object has references to other objects, their reference counts are decreased, and those that are no longer referenced from other objects are also deleted.

The main problem that GCs face is to efficiently find out the reference chains that become circles, because such cyclic references prevent the reference counts to reach 0. This is a well known problem, and various solutions are already implemented in GCs.

The problem with javascript memory leaks stem from the double GCs sweeping the js and DOM realms not being able to properly account for circular dependencies that cross the js-DOM boundary.

I’m not going to go into different patterns of javascript leaks. You can find some patterns in documented in these articles:

Finally, here are some basic rules that will help you avoid javascript memory leaks: 

Using local/temporary variables for DOM objects:
 
If you create a local/temporary variable to hold a DOM object, e.g. the result of getElementById(…), then ensure that you assign null to that variable before you return from the method.

There are two problems you may face when following up this pattern. Firstly, if you have declared an inner method that made use of the local variable holding the reference to the DOM object, then you would find out that the method will complain about trying to access sub-fields of a null object. This is normal, and means that you are structuring your code in a way that might have caused a memory leak. Find another way to implement what you are trying to accomplish.

The other problem arises when you want to return the DOM object that is kept by the local variable, as the return value of your function. In this case, you can use


  var myDomReference;
  // dangerous code that sets fields of myDomReference to functions declared here ...
  try {
    return myDomReference;
  } finally {
    myDomReference = null;
  }

This works, because finally clause will execute after the return statement, but before the function really returns.

IE specific problem: avoid javascript in createElement()

It appears IE has a bug(gy interpretation) of createElement, where you can give it full tags such as

<div onclick="foo()">

Avoid this, not only because it is reported to leak memory for some reason, but also because it is wrong according to the standards, and will prevent your code to work correctly in other browsers.

Ajax leaks

I also suspect that it is possible to create leaks using ajax updates. However, I could not define any patterns about ajax leaks yet. If you know any such patterns, please do share by writing a comment.

Happy coding,
–eg

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir