将img.src设置为dataUrl泄漏内存

Pau*_*ham 9 javascript html5 dom memory-leaks canvas

下面我创建了一个简单的测试用例,它表明当img标签的src设置为不同的dataUrls时,它会泄漏内存.看起来在src更改为其他内容后,图像数据永远不会被卸载.

<!DOCTYPE html>
<html>
  <head>
    <title>Leak Test</title>
    <script type="text/javascript">
      canvas = null;
      context = null;
      image = null;
      onLoad = function(event)
      {
        canvas = document.getElementById('canvas');
        context = canvas.getContext('2d');
        image = document.getElementById('image');
        setTimeout(processImage, 1000);
      }

      processImage = function(event)
      {
        var imageData = null;
        for (var i = 0; i < 500; i ++)
        {
          context.fillStyle = "rgba(" + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + "," + Math.random() +")";
          context.fillRect(0, 0, canvas.width, canvas.height);
          imageData = canvas.toDataURL("image/jpeg", .5);
          image.src = imageData;
        }
        setTimeout(processImage, 1000); 
      }
    </script>
  </head>
  <body onload="onLoad(event)">
    <canvas id="canvas"></canvas>
    <img id="image"></img>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

如果你加载这个html页面,RAM使用会随着时间的推移而建立,并且永远不会被清除.此问题看起来非常相似:使用Data URI快速更新映像会导致缓存,内存泄漏.有什么办法可以防止这种内存泄漏吗?

Pau*_*ham 8

我最终解决了这个问题.只有在更改image.src时才会发生内存膨胀,所以我只是完全绕过了Image对象.我通过获取dataUrl,将其转换为二进制(https://gist.github.com/borismus/1032746),然后使用jpg.js(https://github.com/notmasteryet/jpgjs)解析它.使用jpg.js然后我可以将图像复制回我的画布,因此Image元素完全被subsed,从而无需设置其src属性.