文件读取器内存泄漏

FileReader memory leak

我正在使用 FileReader 将图像文件上传到客户端 用于数据获取和缩略图显示。

我注意到的是, 在页面进程中,在任务管理器中, 记忆力越来越高。 当进程停止时,内存保持高位且永不下降。

你能告诉我我做错了什么吗?

查看请上传200多张图片,最大30MG。 并看到内存不断泄漏

先谢谢你。

-- here is a link to a code example on the web

这是我的代码:

<input class="fu" type="file" multiple="multiple" />
<div class="fin"></div>
<div class="list"></div>

<script type="text/javascript">
    $(document).ready(function () {
        var input = $("body input.fu");

        input[0].addEventListener('change', fu.select, false);
    });

    var fu = {
        list: [],
        index: 0,

        select: function (evt) {
            evt.stopPropagation();
            evt.preventDefault();

            var files = evt.target.files ? evt.target.files : evt.dataTransfer ? evt.dataTransfer.files : []; // FileList object

            fu.list = files;
            fu.index = 0;

            fu.load();
        },

        load: function () {
            var index = fu.index;
            var file = fu.list[index];

            if (file) {
                var reader = new FileReader(); // File API object

                reader.onloadend = (function (theFile) {
                    return function (evt) {
                        if (evt.target.readyState == FileReader.DONE) {
                            setTimeout(fu.load, 20);
                        }
                    };
                })(file);


                reader.onprogress = null;
                reader.onloadstart = null;
                reader.onerror = null;
                reader.onabort = null;

                if (reader.readAsBinaryString) {
                    reader.readAsBinaryString(file);
                } else {
                    reader.readAsDataURL(file);
                }

                fu.index++;
                $('.fin').html("#" + fu.index);
            } else {
                $('.fin').html("finish");
            }

        }
    }
</script>

我刚刚测试了289个文件,没有内存泄漏。这是我使用的 jsfiddle:

http://jsfiddle.net/2pyqjeke/

阅读前:

              total        used        free      shared  buff/cache   available
Mem:           3945        1400         749          23        1796        2253

阅读后:

              total        used        free      shared  buff/cache   available
Mem:           3945        1963         292          23        1690        1690

之后的某个时间:

              total        used        free      shared  buff/cache   available
Mem:           3945        1398         856          23        1690        2255

我正在使用 Firefox 和 Manjaro。

编辑

使用 Chromium,这些是我的结果。

之前:

              total        used        free      shared  buff/cache   available
Mem:           3945        1140         633          52        2171        2476

加载图片后:

              total        used        free      shared  buff/cache   available
Mem:           3945        1573         296          43        2075        2050

之后它就不会停止运行...所以我猜 GC 不会释放文件读取器。所以我对代码做了一个非常小的改动:

http://jsfiddle.net/2pyqjeke/1/

这是 Chromium 中的结果...

之前:

              total        used        free      shared  buff/cache   available
Mem:           3945        1197         672          44        2075        2426

加载图片后:

              total        used        free      shared  buff/cache   available
Mem:           3945        1588         322          44        2034        2035

过了一会儿它下降到:

              total        used        free      shared  buff/cache   available
Mem:           3945        1227         684          44        2034        2397

坦率地说,我不明白为什么 Chromium 不发布 FileReader 而 Firefox 是。

好的,我已经解决了这个问题。

原因是我每次都将 reader 设置为 - new FileReader()。

所以我只让它成为全球。

这是工作代码:

<script type="text/javascript">
    $(document).ready(function () {
        var input = $("body input.fu");

        input[0].addEventListener('change', fu.select, false);
    });

    var fu = {
        list: [],
        index: 0,
        reader: null,

        select: function (evt) {
            evt.stopPropagation();
            evt.preventDefault();

            var files = evt.target.files ? evt.target.files : evt.dataTransfer ? evt.dataTransfer.files : []; // FileList object

            fu.list = files;
            fu.index = 0;

            fu.reader = new FileReader(); // <- made this only once

            fu.load();
        },

        load: function () {
            var index = fu.index;
            var file = fu.list[index];

            if (file) {
                fu.reader.onloadend = (function (theFile) {
                    return function (evt) {
                        if (evt.target.readyState == FileReader.DONE) {
                            fu.reader.abort();

                            setTimeout(fu.load, 5);
                        }
                    };
                })(file);


                fu.reader.onprogress = null;
                fu.reader.onloadstart = null;
                fu.reader.onerror = null;
                fu.reader.onabort = null;

                if (fu.reader.readAsBinaryString) {
                    fu.reader.readAsBinaryString(file);
                } else {
                    fu.reader.readAsDataURL(file);
                }

                fu.index++;
                $('.fin').html("#" + fu.index);
            } else {
                $('.fin').html("finish");
            }

        }
    }
</script>