Lately we experienced a lot of performance problems in our AJAX applications. Since we went online a year ago we always had problems with users of Internet Explorer 6 but within the last three months they got more and more.
We already knew that this had something to do with the huge memory amount the Internet Explorer 6 uses after some hours of working with our application. I used the Process Explorer to analyze which page causes the problem. After identifying the page I did some reloads of it and generated the following image:
As you can see, with every reload the memory amount consumed by the Internet Explorer 6 increased (for about 2 megabytes). This memory amount was never released, even if a complete different page of the application was loaded. The only way to release the memory again was to close the instance of the browser.
I was really shocked when I realized that the Internet Explorer 6 holds those elements in memory even after the user left the page and loaded another one. In other browser it is just important to make sure that inside the page the references to elements are released proper when working with a lot of AJAX code without reloading the page.
With sIEve it was easy to detect to suspicious elements. After reloading the page inside of sIEve a lot of possible leaks were detected and the list looked like this:
By looking through the code of the page I found out that all the elements in the list had events registered (onclick, onkeyup, onchange, …) and the assigned methods contained closures (see this link for details again).
Some were caused by the used calendar library. I already sent an email to the author Mihai Bazon. He wrote a very good article about the problem and I could not believe that there is exactly that bug inside his library. Maybe we are using it incorrect.
The other leaks were caused by prototype. Although prototype has a built in mechanism that should unlink registered events when the page is unloaded they survived the reload. I found out that there is a bug in the 1.6.0 version of prototype. The mechanism was changed between version 1.5 and 1.6. This explained why the problem got bigger after updating out application to the new prototype version.
To fix the problem I registered a method to the unload event of the page that removes all the critical registered events. This looks like:
After changing the page like that I tested it again with sIEve and no more leaks were detectd. Then I used the Process Explorer again to monitor the memory consumption of the Internet Explorer. The graph now looked like:
The memory footprint is a lot smaller now and memory allocated by the reload was completely released again.