Legacy IE-JScript circular memory leak problem being worked out.

People are already aware of IE-JScript circular memory leak problem. Let me take some time and explain in detail the reasons behind this. I will take a simple example which will demonstrate the leak. Let's say we have this script block within the HTML page.

<script>
createElem = document.createElement;

function createCircRef()
{
var elem = createElem("DIV");
elem.foo = new Object();
elem.foo.bar = elem;

    return elem;
}

/*This big loop is just to make sure that we see a substantial memory leak in task manager on hitting F5 in IE.*/

var arr = new Array();
var ntimes = 100000;

for (var i = 0; i < ntimes; i++)
{
arr[i] = createCircRef();
}
</script>

For some time we will closely examine this script block. The Jscript function createCircRef()  creats a new element with tag "DIV" and stores it in elem variable. This variable elem is created in host world (in this case Internet Explorer). The next statement creates a new JScript object and assigns it to foo which is an expando inserted on elem variable. At this point of time a new Object is created and stored in JScript world and since elem.foo is pointing to it the reference count of the object will be one. The next line is the problematic line since this is adding expando named bar on newly just created Object and this is pointing to elem. So elem reference count will be increased by 1.

Now we have a situation where an object in JScript world is pointed by a foreign element named elem which exists in IE world and the same Jscript Object is pointing back to elem through it's own expando. The Garbage Collector sitting inside JScript is a nongenerational mark and sweep collector. It is very well capable of resolving any circular references provided the reference is within JScript memory pool. However in this case, when the GC tries to unmark a variable for getting collected it sees that the Object() created by new operator is still referenced. On hitting F5 (doing a page refresh) in IE, IE while trying to release the variable elem finds out that it is referenced by someone and so it is not released. On Jscript side, GC is waiting for elem to release the reference to Object(). Overall we have a situation where IE is waiting on JS and vice-versa and we have a deadlock. This memory will never get released. And each time you hit refresh it will add up.

The above example is not a real world scenario, but there may be real world application doing the same thing. This will hog your system resource (memory here) and may slow down IE or the entire system for that matter. Yes, there are ways to break this kind of circular leaks by following some programming guidelines. Justin Rogers from the Internet Explorer team has written a nice article regarding how to break this kind of loop pragmatically and can be found here.

Much has been written already about this and you must be wondering why am I writing this again. The good news is that the team has started looking at a fix for this and we do have a prototype ready. With AJAX becoming more and more famous and Jscript being used heavily rather than just few lines of code within HTML, the thinking is that this will really help the programmers a lot. We are still looking at various scenarios where memory leaks and coming up with a solution which will address all or most of it. But this will definitely make it in one of our future releases.

Apart from this the team is also working on providing a rich set of tools for development within Internet Explorer like profiler and debugger which will help an AJAX developer in developing the code in Internet Explorer. Team is also actively working on providing support for a great authoring in Visual Studio Orcas including Syntax Checking and Intellisense. 

We would also like to hear from you regarding what kind of tool set and features you are looking for. So do post your comments/suggestions....

Thanks,

Don Raman

Senior Test Lead