javascript - Chrome 中的 CreateObjectURL 内存泄漏

标签 javascript google-chrome memory memory-leaks

我正在开发一个网络应用程序,每个人都可以直接在互联网上编辑图像。

在开发网站时,我遇到了打开本地系统文件的大问题。

通常,我们可以使用如下两种已知的方式来做到这一点。

首先,使用FileReader

// render the image in our view
function renderImage(file) {

  // generate a new FileReader object
  var reader = new FileReader();

  // inject an image with the src url
  reader.onload = function(event) {
    the_url = event.target.result
    $('#some_container_div').html("<img src='" + the_url + "' />")
  }

  // when the file is read it triggers the onload event above.
  reader.readAsDataURL(file);
}

// handle input changes
$("#the-file-input").change(function() {
    console.log(this.files)

    // grab the first image in the FileList object and pass it to the function
    renderImage(this.files[0])
});

其次,使用 createObjectURL 和 revokeObjectURL。

   window.URL = window.URL || window.webkitURL;

var fileSelect = document.getElementById("fileSelect"),
    fileElem = document.getElementById("fileElem"),
    fileList = document.getElementById("fileList");

fileSelect.addEventListener("click", function (e) {
  if (fileElem) {
    fileElem.click();
  }
  e.preventDefault(); // prevent navigation to "#"
}, false);

function handleFiles(files) {
  if (!files.length) {
    fileList.innerHTML = "<p>No files selected!</p>";
  } else {
    fileList.innerHTML = "";
    var list = document.createElement("ul");
    fileList.appendChild(list);
    for (var i = 0; i < files.length; i++) {
      var li = document.createElement("li");
      list.appendChild(li);

      var img = document.createElement("img");
      img.src = window.URL.createObjectURL(files[i]);
      img.height = 60;
      img.onload = function() {
        window.URL.revokeObjectURL(this.src);
      }
      li.appendChild(img);
      var info = document.createElement("span");
      info.innerHTML = files[i].name + ": " + files[i].size + " bytes";
      li.appendChild(info);
    }
  }
}

就我而言,它们都不能在 Chrome 浏览器中正常运行。 (IE 没问题) 我可以同时使用它们来打开本地文件。而且,即使我在使用第二种方式时准确调用了 revokeObjectURL,那些总是会导致内存泄漏。

我已经检查过 chrome://blob-internals/ 中的 blob 是否正常发布。所有的 blob 都发布得很好。但是,Chrome 仍然保留物理内存,除非我刷新页面,否则内存不会永远释放。最终,当内存使用量达到 1.5GB 时,Chrome 崩溃了。

FileReader 向我展示了相同的结果,尽管我发布了 refs。此外,这种方式显示出糟糕的 I/O 性能。

http://ecobyte.com/tmp/chromecrash-1a.html (来自 logidelic)

这是一个测试页面。您可以通过将文件拖放到绿色 DOM 上来测试这个问题。测试页面使用了createObjectURL/revokeObjectURL方法。

当您进行此测试时,您可以从任务管理器 (Shift + ESC) 或您自己的操作系统任务管理器中看到物理内存消耗。

我是否遗漏了什么,或者这是一个已知的错误?

拜托,有人帮帮我!如果您知道解决此问题的另一种方法,请告诉我。

最佳答案

createObjectURL 方法也有同样的问题。最后发现在onload函数中加入代码可以释放内存:

this.src = '';

但是,如您所料,图像将从网页上消失。 此外,我还注意到有时 chrome (50.0.2661.102) 或 chrome canary (52.0.2740.0) 即使使用 this.src= '' 也无法释放内存。一旦发生,您需要重新启动 chrome。简单地刷新页面是行不通的。

我也尝试过 readAsDataURL 方法。可以很好地释放内存(即使chrome无法为this.src=''的createObjectURL释放内存。)但是,缺点是速度相当慢(与createObjectURL相比大约长10倍)。

关于javascript - Chrome 中的 CreateObjectURL 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33667099/

相关文章:

c - 在结构函数中分配动态数组

javascript - 语法错误 : "Unexpected token <" in Web Console

linux - Nginx 因 “Out of memory” 被杀死?

javascript - 我怎样才能把这个让这个框像图片中那样放在文本下面

javascript - 未捕获的类型错误 : Cannot read property 'chooseEntry' of undefined (while developing a chrome extension using fileSystem API)

google-chrome - 匿名代理不仅仅适用于 Firefox。对于 Chrome - 确定

google-chrome - 在调试 Chrome 扩展程序时,有没有办法让开发人员工具保持打开状态?

c - 我该如何解决这个递归溢出?

javascript - 如何让 requirejs 适用于第三方库 (interact.js)?

javascript - 根据选择值克隆表单