title: Is Internet Explorer 9 (IE9) leaking during ajax / web service calls?
body: <p>I think I may have discovered quite a bad memory leak in Internet Explorer 9. It seems that when doing AJAX calls to a web service, IE9 leaks memory each time. In fact it seems to leak more memory than the size of the transfer involved.</p>
  
  <p>If you watch the IE9 process in task manager you see the memory usage climb (and never fall). The browser eventually uses ~1.5GB of memory at which point the application crashes. Obviously this would be a problem if you are trying to develop an AJAX web app that is meant to stay running for days at a time.</p>
  
  <p>This behaviour does not occur on IE8, Chrome or Firefox. I have also tested IE9 with all addons disabled.</p>
  
  <p>Below is some ASP.NET 2.0 code that can reproduce the problem (you will need the MS ASP.NET AJAX extensions if you wish to try it):</p>
  
  <pre><code>&lt;%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebServiceLeakTest._Default" %&gt;
  
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  
  &lt;html xmlns="http://www.w3.org/1999/xhtml" &gt;
  &lt;head runat="server"&gt;
      &lt;title&gt;Web Service Leak Test&lt;/title&gt;
      &lt;script type="text/javascript" src="jQuery-1.7.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="json2.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript"&gt;        
          $(document).ready(function()
          {
              resultsArea = jQuery("#results");                       
              resultsArea.html(iterationCount);                
              GetData();                        
          });
  
          var resultsArea;
  
          var iterationCount = 0;                
  
          var useJQuery = false;
  
          var waitInterval = 1500;
  
          function GetData()
          {
              if(useJQuery)
              {
                  $.ajax(
                      {
                          url: "TestWebService.asmx/GetSomeData",
                          type: "POST",
                          contentType: "application/json; charset=utf-8",
                          dataType: "json",
                          success: ReceiveData,
                          error: ReceiveError
                      });
              }
              else
              {            
                  WebServiceLeakTest.TestWebService.GetSomeData(ReceiveData, ReceiveError);
              }
          }
  
          function ReceiveData(data)
          {
              resultsArea.html(iterationCount++);                
              setTimeout(GetData, waitInterval);
          }
  
          function ReceiveError(error)
          {
  
          }
      &lt;/script&gt;    
  &lt;/head&gt;
  &lt;body&gt;
      &lt;form id="form1" runat="server"&gt;
          &lt;asp:ScriptManager ID="ScriptManager1" runat="server"&gt;
              &lt;Services&gt;       
                  &lt;asp:ServiceReference Path="TestWebService.asmx" /&gt;
              &lt;/Services&gt;
          &lt;/asp:ScriptManager&gt;
      &lt;div id="results"&gt;
          !
      &lt;/div&gt;    
      &lt;/form&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>You will notice from the code that the results returned from the web service call are not even stored in the javascript client; it merely updates a counter when the web service returns.</p>
  
  <p>Also, this problem occurs when using either the auto-generated client stubs from the ServiceReference or when using jQuery (change 'useJQuery' to true). I have also tried using jQuery with json2.js for the (de)serialisation with jQuery, but this made no apparent difference.</p>
  
  <p>Here is the code for the test web service:</p>
  
  <pre><code>using System;
  using System.Data;
  using System.Web;
  using System.Collections;
  using System.Web.Services;
  using System.Web.Services.Protocols;
  using System.ComponentModel;
  using System.Collections.Generic;
  using System.Web.Script.Services;
  
  namespace WebServiceLeakTest
  {
      [WebService(Namespace = "http://tempuri.org/")]
      [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
      [ToolboxItem(false)]
      [ScriptService]
      public class TestWebService : System.Web.Services.WebService
      {
          const int NUMBER_OF_RECORDS = 10;
  
          [WebMethod]
          public List&lt;TestData&gt; GetSomeData()
          {
              List&lt;TestData&gt; data = new List&lt;TestData&gt;(NUMBER_OF_RECORDS);
  
              for (int i = 0; i &lt; NUMBER_OF_RECORDS; i++)
              {
                  TestData record = new TestData(
                      Guid.NewGuid().ToString(),
                      Guid.NewGuid().ToString(),
                      Properties.Resources.LorumIpsum);
  
                  data.Add(record);
              }
  
              return data;
          }
      }
  }
  </code></pre>
  
  <p>As you can probably see, it doesn't do much special. It returns some dumb objects containing 3 string properties. Each of these dumb objects is populated with 2 GUIDs and about 70KB of arbitrary text. Therefore, each call to the web service is returning ~700KB.</p>
  
  <p>If you try this out, you will need to increase the max JSON transfer length in your web.config file.</p>
  
  <p>e.g. &lt;jsonSerialization maxJsonLength="10000000" /></p>
  
  <p>I have searched the web, MSDN etc but can not find anything useful or informative regarding this problem.</p>
  
  <p>Has anyone else encountered this? Am I doing something wrong? Can anyone else reproduce this problem? Have I found a bad memory leak in IE9?</p>
  
  <p>Regards,
  James</p>