【发布时间】:2017-05-02 02:30:15
【问题描述】:
我有一个带有文件上传功能的网页。上传以 5MB 块执行。我想在将每个块发送到服务器之前计算它的哈希值。块由Blob 对象表示。为了计算哈希值,我正在使用本机 FileReader 将此类 blob 读入 ArrayBuffer。代码如下:
var reader = new FileReader();
var getHash = function (blob, callback) {
reader.onloadend = function (e) {
var hash = util.hash(e.target.result);
callback(hash);
};
reader.readAsArrayBuffer(blob);
}
var processChunk = function (chunk) {
if (chunk) {
getHash(chunk, function (hash) {
util.sendToServer(chunk, hash, function() {
// this callback is called when chunk upload is finished
processChunk(chunks.shift());
});
});
}
}
var chunks = file.splitIntoChunks(); // gets an array of blobs
processChunk(chunks.shift());
问题:使用FileReader.readAsArrayBuffer 似乎会占用大量未释放的内存。到目前为止,我在以下浏览器上使用 5GB 文件进行了测试:
Chrome 55.0.2883.87 m(64 位):内存快速上升到 1-2GB 并在此附近振荡。有时它会一直上升并且浏览器选项卡崩溃。它可以使用比读取块的大小更多的内存。例如。在读取 500MB 块后,进程已经使用了 700MB 内存。
Firefox 50.1.0:内存使用量在 300-600MB 左右波动
我尝试过的代码调整 - 都无济于事:
- 为所有块重新使用相同的
FileReader实例(如this question 中所建议的那样) - 为每个块创建新的
FileReader - 在开始新块之前添加超时
- 在每次读取后将
FileReader和ArrayBuffer设置为 null
问题:有没有办法解决这个问题?这是 FileReader 实现中的错误还是我做错了什么?
编辑:这是一个 JSFiddle https://jsfiddle.net/andy250/pjt9udeu/
【问题讨论】:
-
我也尝试过使用 Chrome 55.0.2883.87 m(64 位) - 运行 JsFiddle 时消耗的内存大致相同。见视频剪辑:screencast.com/t/e7eQkVMWI68a。还测试了 Internet Explorer 11 - 它只使用了大约 130 MB RAM。
标签: javascript memory file-upload memory-leaks filereader