FileReader:使用javascript读取多个文件而无内存泄漏

FileReader:使用javascript读取多个文件而无内存泄漏,javascript,file,Javascript,File,在网页中,我必须读取文件的一小部分,这对于许多(1500-12000)小文件来说,每个文件大约有1MB大。一旦我收集了我需要的信息,我就把它推回到服务器上 我的问题是:我使用FileReaderAPI,垃圾收集不起作用,内存消耗激增 代码如下: function extract_information_from_files(input_files) { //some dummy implementation for (var i = 0; i < input_files.length;

在网页中,我必须读取文件的一小部分,这对于许多(1500-12000)小文件来说,每个文件大约有1MB大。一旦我收集了我需要的信息,我就把它推回到服务器上

我的问题是:我使用FileReaderAPI,垃圾收集不起作用,内存消耗激增

代码如下:

function extract_information_from_files(input_files) {

//some dummy implementation
for (var i = 0; i < input_files.length; ++i) {


    (function dummy_function(file) {

        var reader = new FileReader();

        reader.onload = function () {

            //convert to Uint8Array because used library expects this

            var array_buffer = new Uint8Array(reader.result);

            //do some fancy stuff with the library (very small subset of data is kept)

            //finish

            //function call ends, expect garbage collect to start cleaning.
            //even explicit dereferencing does not work
        };

        reader.readAsArrayBuffer(file);

    })(input_files[i]);

}
函数从文件中提取信息(输入文件){
//一些虚拟实现
对于(变量i=0;i
}

一些评论:

  • 不,乍一看,库似乎没有保留对加载对象的任何引用。即使您像上面所示那样运行代码,并且根本不使用array_buffer,所有内容都保存在内存中
  • 行为因浏览器而异:
  • 铬(43)并不能完全清除任何东西
  • Firefox(38)似乎使用的剩余内存约为所有文件大小的1/3
  • 我发现在互联网上讨论同样问题的话题非常少。我试过的是:
  • ->旧的File.prototype.mozSlice已更改为.slice,但即使如此,问题仍然存在
  • ->建议的解决方案不起作用
  • 我不太清楚。->首先,您似乎不需要取消引用(请参见对象不需要vs.对象不可访问),但它们还声明了“限制:需要将对象显式设置为不可访问”
最后一个奇怪的细节(为了完整性而发布),当使用FileReader与结合使用时,我在将文件推送到zip存档之前读取了一个文件,垃圾收集就起作用了


所有这些评论似乎都指向我无法正确使用FileReader,因此请告诉我如何使用。

问题可能与执行顺序有关。在
for
循环中,您正在使用
reader.readAsArrayBuffer(文件)
读取所有文件。此代码将在为读卡器运行任何
onload
之前运行。根据
FileReader
的浏览器实现,这可能意味着浏览器在调用任何
onload
之前加载整个文件(或只是为整个文件预先分配缓冲区)

试着像处理队列一样处理文件,看看这是否会有所不同。比如:

function extract_information_from_files(input_files) {
    var reader = new FileReader();

    function process_one() {
        var single_file = input_files.pop();
        if (single_file === undefined) {
            return;
        }

        (function dummy_function(file) {
            //var reader = new FileReader();

            reader.onload = function () {
                // do your stuff
                // process next at the end
                process_one();
            };

            reader.readAsArrayBuffer(file);
        })(single_file);
    }

    process_one();
}

extract_information_from_files(file_array_1);
// uncomment next line to process another file array in parallel
// extract_information_from_files(file_array_2);

编辑:浏览器似乎希望您重用
文件阅读器
。我对代码进行了编辑,以重用单个读卡器,并(在chrome中)测试了内存使用限制为您读取的最大文件。

谢谢您的建议。我更正了我最初的帖子,因为我现在看到了不同浏览器的不同行为。然而,你的建议似乎没有任何区别。我们有FileReaderI的替代品吗?我不认为还有其他替代API。至少具有相同的标准化水平。不过,奇怪的是,我的建议没有产生任何不同。我将进行调查,因为我也有兴趣知道原因。在测试之后,我可以复制您描述的问题,而且似乎浏览器所做的任何内存管理都假定您使用的
FileReader
实例很少。