19 Comments

jQuery Ajax Memory Leak in IE8

I was surprised to find out last week that Ajax calls made with jQuery 1.4.2 leak memory in Internet Explorer 8.

The web application I am working on includes a page on which a user will spend much of their time. As the user navigates through various subsections of the page (we are using sammy.js for client side “pages”) repeated Ajax requests are made to the server for JSON data. Our exploratory tester discovered that the page was slowing down dramatically in IE8 the longer he navigated through the subsections. Further investigation revealed that the browser’s memory usage was increasing dramatically over time.

After a fair amount of trial and error I was finally able to narrow the leak down to the Ajax calls. I made a test html file that did nothing but make repeated Ajax requests and watched the memory increase. My test page used jQuery 1.4.2 because that is what the application was using.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
  <head>
    <script type="text/javascript" src="/javascripts/jquery-1.4.2.js"></script>
    <script type="text/javascript">
      var requestData = function() {
        $.ajax({ 
          url: 'http://localhost/data.json',
          type: 'GET',
          contentType: 'application/json',
          complete: function() {
            setTimeout(requestData, 100);
          }
        });
      }
      $(requestData)
    </script>
  </head>
  <body>
    Memory Leak Testing...
  </body>
</html>

Knowing it had something to do with Ajax I was able to find a stackoverflow question that described my problem exactly. One of the answers referenced an open ticket on the jQuery project site that included a patch for jQuery 1.4.2. The ticket has been open for 7 months so far and has yet to be corrected in the jQuery code base. A commenter on the submitted ticket indicated this was also a problem in IE7, but I have not confirmed that myself.

I applied the patch to my local copy of jQuery 1.4.2, ran my test page, and happily watched as the memory no longer increased over time.

The original jQuery code (around line 5223):

1
2
3
    if ( s.async ) {
      xhr = null;
    }

The modified jQuery code:

1
2
3
    if ( s.async ) {
      xhr.onreadystatechange = null; xhr.abort = null; xhr = null;
    }

With so many javascript memory leaks in Internet Explorer it can be very difficult to track down the cause and solution to any given leak. The last place I thought to look was in the most popular javascript library in the world. For pages that make a limited number of Ajax requests this leak is probably not an issue. But for any page that does continuous polling, or where a user can make numerous requests, it is most definitely a problem.