首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Chrome中的CreateObjectURL内存泄漏

Chrome中的CreateObjectURL内存泄漏
EN

Stack Overflow用户
提问于 2015-11-12 16:27:53
回答 1查看 1.5K关注 0票数 4

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

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

通常,我们可以通过两种已知的方法来实现这一点,如下所示。

首先,使用FileReader

代码语言:javascript
复制
// 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。

代码语言:javascript
复制
   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/中释放得很好。所有的斑点都释放得很好。但是,Chrome仍然保留了物理内存,除非我刷新页面,否则内存不会永远释放。最终,当内存使用量达到1.5 up时,Chrome崩溃了。

FileReader向我展示了相同的结果,尽管我发布了参考文献。此外,该方法显示出糟糕的I/O性能。

http://ecobyte.com/tmp/chromecrash-1a.html (通过logidelic)

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

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

我是否遗漏了什么,或者是已经知道的bug?

快来人救救我!如果你知道解决这个问题的其他方法,请告诉我。

EN

回答 1

Stack Overflow用户

发布于 2016-05-20 15:41:41

我对createObjectURL方法也有同样的问题。最后,我发现可以通过在onload函数中添加代码来释放内存:

代码语言:javascript
复制
this.src = '';

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33667099

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档