我正在开发一个web应用程序,每个人都可以直接在互联网上编辑图像。
在开发站点时,我遇到了一个打开本地系统文件的大问题。
通常,我们可以通过两种已知的方法来实现这一点,如下所示。
首先,使用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/中释放得很好。所有的斑点都释放得很好。但是,Chrome仍然保留了物理内存,除非我刷新页面,否则内存不会永远释放。最终,当内存使用量达到1.5 up时,Chrome崩溃了。
FileReader向我展示了相同的结果,尽管我发布了参考文献。此外,该方法显示出糟糕的I/O性能。
http://ecobyte.com/tmp/chromecrash-1a.html (通过logidelic)
这是一个测试页面。你可以通过将文件放到绿色的DOM上来测试这个问题。测试页面使用的是createObjectURL/revokeObjectURL方法。
在执行此测试时,您可以从任务管理器(Shift + ESC)或您自己的操作系统任务管理器中查看物理内存消耗情况。
我是否遗漏了什么,或者是已经知道的bug?
快来人救救我!如果你知道解决这个问题的其他方法,请告诉我。
发布于 2016-05-20 15:41:41
我对createObjectURL方法也有同样的问题。最后,我发现可以通过在onload函数中添加代码来释放内存:
this.src = '';但是,如您所料,图像将从网页中消失。此外,我还注意到,即使使用this.src= '‘,chrome (50.0.2661.102)或chrome canary (52.0.2740.0)有时也无法释放内存。一旦发生这种情况,你需要重新启动chrome。简单地刷新页面是行不通的。
我也尝试过readAsDataURL方法。可以很好地释放内存(即使chrome无法使用this.src=‘’为createObjectURL释放内存)。然而,缺点是速度相当慢(与createObjectURL相比大约长10倍)。
https://stackoverflow.com/questions/33667099
复制相似问题