FileReader似乎消耗了所有内存,因为它被重复用于预加载多个blob,并且永远不会释放它。任何已知的方法强制它释放消耗的内存?将FileReader对象及其result属性设置为null似乎不起作用。
更新
这是一个sample code(在大文件上测试它,比如电影,或者你不会注意到任务管理器中的效果):
<input id="file" type="file" onchange="sliceMe()" />
<script>
function sliceMe() {
var file = document.getElementById('file').files[0],
fr,
chunkSize = 2097152,
chunks = Math.ceil(file.size / chunkSize),
chunk = 0;
function loadNext() {
var start, end,
blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice;
start = chunk * chunkSize;
end = start + chunkSize >= file.size ? file.size : start + chunkSize;
fr = new FileReader;
fr.onload = function() {
if (++chunk < chunks) {
// shortcut - in production upload happens and then loadNext() is called
loadNext();
}
};
fr.readAsBinaryString(blobSlice.call(file, start, end));
}
loadNext();
}
</script>
我每次尝试创建新的FileReader实例,但问题仍然存在。我怀疑它可能是由图案的圆形特性引起的,但我不确定在这种情况下可以使用哪种其他图案。
我在Firefox和Chrome中检查了这段代码,Chrome似乎更优雅地处理它 - 它在每个周期后清除内存并且非常快。但具有讽刺意味的是,Chrome根本不需要使用此代码。这只是一个克服Gecko 6-FormData + Blob bug(Bug 649150 - Blobs do not have a filename if sent via FormData)的实验。
答案 0 :(得分:4)
请尝试这样:
function sliceMe() {
var file = document.getElementById('file').files[0],
fr = new FileReader,
chunkSize = 2097152,
chunks = Math.ceil(file.size / chunkSize),
chunk = 0;
function loadNext() {
var start, end,
blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice;
start = chunk * chunkSize;
end = start + chunkSize >= file.size ? file.size : start + chunkSize;
fr.onload = function() {
if (++chunk < chunks) {
//console.info(chunk);
}
};
fr.onloadend = function(e) {
loadNext(); // shortcut here
};
fr.readAsBinaryString(blobSlice.call(file, start, end));
}
loadNext();
}
onloadend会让你不会重复你的其他阅读...(显然,你可以更好地修正增量,但你明白了......)
答案 1 :(得分:3)
Bug已被标记为INVALID,因为事实证明我实际上并没有正确地重新使用FileReader对象。
这是一个模式,它不会占用内存和cpu:
function sliceMe() {
var file = document.getElementById('file').files[0],
fr = new FileReader,
chunkSize = 2097152,
chunks = Math.ceil(file.size / chunkSize),
chunk = 0;
function loadNext() {
var start, end,
blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice;
start = chunk * chunkSize;
end = start + chunkSize >= file.size ? file.size : start + chunkSize;
fr.onload = function() {
if (++chunk < chunks) {
//console.info(chunk);
loadNext(); // shortcut here
}
};
fr.readAsBinaryString(blobSlice.call(file, start, end));
}
loadNext();
}
另一个错误报告已经提交:https://bugzilla.mozilla.org/show_bug.cgi?id=681479,这是相关的,但在这种情况下不是邪恶的。
感谢Kyle Huey引起我的注意:)