title: Memory Management with Repeating jQuery Datatables AJAX Calls
body: <p>I'm fairly new to javascript and jQuery, so please excuse any incorrect verbiage in my problem description.  </p>
  
  <p><strong>Background</strong>: I have a site where I'm using the <a href="http://datatables.net" rel="nofollow">Datatables</a> plugin for jQuery to display a live, realtime display of a SQL table.  The SQL query is processed in ASP.NET and returned to the client as a JSON object.  Right now, I'm only displaying ~500 records.  </p>
  
  <p>Once the JSON object has been parsed by the datatables plugin, I perform some conditional formatting of the table cells -- hence there could be some heavy DOM manipulation if I understand that concept correctly.  I've read that this can be where a lot of memory leaks can occur, but I also thought that jQuery was pretty solid at cleaning up after itself.  </p>
  
  <p>I'm using a setInterval timer to update the datatable periodically such that it displays changes in real time.  </p>
  
  <p><strong>My Problem</strong>: Memory consumption of my site is out of control.  On every AJAX call (~every 2 sec), the memory usage for the page can jump as much as 2MB.  To throttle this back, I installed an <a href="http://www.bedroomlan.org/coding/detecting-%E2%80%98idle%E2%80%99-and-%E2%80%98away%E2%80%99-timeouts-javascript" rel="nofollow">idle plugin</a> for jQuery to detect when the user is active on the site - and I reduce the AJAX calls to ~every 1 hour when the user is idle.  I heard that this can give more space for the browser to perform garbage collection.</p>
  
  <p>What I find is that memory climbs pretty continuously while active, with a slight drop every 4 or 5 calls where it looks like some garbage collection is being performed.  Memory does not climb when the AJAX calls are reduced while the user is idle.  Below, I've pasted a stripped down version of my code (excluding some irrelevant snippets).  I'm sure it's not the cleanest code - but if someone could provide a pointer as to what might be causing the memory consumption -- or how I could reduce the consumption, it would be greatly appreciated.  </p>
  
  <p>Thanks in advance!</p>
  
  <pre><code>    //TIMER
      var updateFreq = 5000;
      var timer;
  
      setIdleTimeout(5000); // 5 seconds
      setAwayTimeout(50000); // 10 seconds
      document.onIdle = function() {
          clearInterval(timer);
          updateTable(3600000); //update once an hour
          //if (typeof (CollectGarbage) == "function") { CollectGarbage(); }
      }        
      document.onAway = function() { 
          clearInterval(timer);
          updateTable(3600000); //update once an hour
          //if (typeof (CollectGarbage) == "function") { CollectGarbage(); }
       }  
      document.onBack = function(isIdle, isAway) {
          clearInterval(timer);
          updateTable(5000); //update once every two seconds
      }
      //END TIMER
  
      var oTable;
      var oSettings;
  
  $(document).ready(function() {
      oTable = $("#production_table").dataTable({
              "sDom": '&lt;"TT"T&gt;&lt;"tab"t&gt;&lt;"F"fip&gt;',
              "iDisplayLength": -1,
              "sAjaxSource": 'Data.ashx',
              // "sScrollY": y - 217,
              //"sScrollX": "100%",
              "bJQueryUI": true,
              "bDeferRender": true,
              // "bStateSave": true,
              "aaSorting": [[16, 'desc']],
              "sPaginationType": "full_numbers",
              //        "bAutoWidth": false,
              "fnDrawCallback": function(oSettings) {
                  addFormat();
                  try {
                      $('td').disableTextSelect();
                  }
                  catch (err) {
                  }
              },
              "fnServerData": function(sSource, aoData, fnCallback) {
                  $.ajax({
                      dataType: 'json',
                      type: "GET",
                      cache: false,
                      url: sSource,
                      data: aoData,
                      success: fnCallback
                  })
              },
              "fnInitComplete": function(oSettings, json) {
                  //alert('DataTables has finished its initialisation.');
                  //                    addFormat();
  
                  //$('td').disableTextSelect();
              },
              // "bProcessing": true,
              "aoColumns": [
                      { "mDataProp": null, "bSortable": false },
                      { "mDataProp": "serial", "sClass": "serial" },
                      { "mDataProp": "us", "sClass": "us" },
                      { "mDataProp": "type", "sClass": "type" },
                      { "mDataProp": "compartment", "sClass": "compartment" },
                      { "mDataProp": "leg", "sClass": "leg", "bVisible": false },
                      { "mDataProp": "comp", "sClass": "comp", "bVisible": false },
                      { "mDataProp": "patient", "sClass": "patient", "bVisible": false },
                      { "mDataProp": "dob", "sClass": "dob", "bVisible": false },
                      { "mDataProp": "surgeon", "sClass": "surgeon", "bVisible": false },
                      { "mDataProp": "surgery", "sClass": "surgery", "bVisible": false }
  //I've truncated this section slightly...
                  ]
  
          });
      updateTable(updateFreq);
  });
  
  
  
  function updateTable(uF) {
      // Update the table using the fnReloadAjax call method
          timer = setInterval(function() {
              var iStart = oSettings._iDisplayStart;
              oSettings = oTable.fnSettings();
              oTable.fnReloadAjax();
              //oTable.fnDisplayStart(oSettings, iStart, true);
          }, uF);
      }
  </code></pre>