title: Data URI leak in Safari (was: Memory Leak with HTML5 canvas)
body: <p>I have created a webpage that receives base64 encoded bitmaps over a Websocket and then draws them to a canvas.  It works perfectly.  Except, the browser's (whether Firefox, Chrome, or Safari) memory usage increases with each image and never goes down.  So, there must be a memory leak in my code or some other bug.  If I comment out the call to context.drawImage, the memory leak does not occur (but then of course the image is never drawn).  Below are snippets from my webpage.  Any help is appreciated.  Thanks!  </p>
  
  <pre><code>// global variables
  var canvas;
  var context;
  
  ...
  
  ws.onmessage = function(evt)
  {
      var received_msg = evt.data;
      var display_image = new Image();
      display_image.onload = function ()
      {
          context.drawImage(this, 0, 0);
      }
      display_image.src = 'data:image/bmp;base64,'+received_msg;
  }
  
  ...
  
  canvas=document.getElementById('ImageCanvas');
  context=canvas.getContext('2d');
  
  ...
  
  &lt;canvas id="ImageCanvas" width="430" height="330"&gt;&lt;/canvas&gt;
  </code></pre>
  
  <hr>
  
  <p>UPDATE 12/19/2011</p>
  
  <p>I can work around this problem by dynamically creating/destroying the canvas every 100 images or so with createElement/appendChild and removeChild.  After that, I have no more memory problems with Firefox and Chrome.</p>
  
  <p>However, Safari still has a memory usage problem, but I think it is a different problem, unrelated to Canvas.  There seems to be an issue with repeatedly changing the "src" of the image in Safari, as if it will never free this memory.</p>
  
  <pre><code>display_image.src = 'data:image/bmp;base64,'+received_msg;  
  </code></pre>
  
  <p>This is the same problem described on the following site: <a href="http://waldheinz.de/2010/06/webkit-leaks-data-uris/" rel="noreferrer">http://waldheinz.de/2010/06/webkit-leaks-data-uris/</a></p>
  
  <hr>
  
  <p>UPDATE 12/21/2011</p>
  
  <p>I was hoping to get around this Safari problem by converting my received base64 string to a blob (with a "dataURItoBlob" function that I found on this site) and back to a URL with window.URL.createObjectURL, setting my image src to this URL, and then later freeing the memory by calling window.URL.revokeObjectURL.  I got this all working, and Chrome and Firefox display the images correctly.  Unfortunately, Safari does not appear to have support for BlobBuilder, so it is not a solution I can use.  This is strange, since many places including the O'Reilly "Programming HTML5 Applications" book state that BlobBuilder is supported in Safari/WebKit Nightly Builds.  I downloaded the latest Windows nightly build from <a href="http://nightly.webkit.org/" rel="noreferrer">http://nightly.webkit.org/</a> and ran WebKit.exe but BlobBuilder and WebKitBlobBuilder are still undefined.</p>
  
  <hr>
  
  <p>UPDATE 01/03/2012</p>
  
  <p>Ok, I finally fixed this by decoding the base64-encoded data URI string with atob() and then creating a pixel data array and writing it to the canvas with putImageData (see <a href="http://beej.us/blog/2010/02/html5s-canvas-part-ii-pixel-manipulation/" rel="noreferrer">http://beej.us/blog/2010/02/html5s-canvas-part-ii-pixel-manipulation/</a>).  Doing it this way (as opposed to constantly modifying an image's "src" and calling drawImage in the onload function), I no longer see a memory leak in Safari or any browser.  </p>