问题
I'm using FileReader to upload image files to a client for data fetching and thumbnails display.
what I've noticed is, that on the page process, in task manager, the memory just keeps going higher and higher. and when the process stops, and memory stay high and never goes down.
can you please tell me what I am doing wrong here?
to check, please upload more then 200 pictures, up to 30MG. and see that the memory keeps on leaking
thank you in advanced.
-- here is a link to a code example on the web
and here is my code:
<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>
回答1:
ok, I have fixed this.
the reason was that I set reader to - new FileReader() - each time.
so I only made it global.
here is the working code:
<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>
回答2:
I just tested it with 289 files and there's no memory leak. Here's the jsfiddle I use:
http://jsfiddle.net/2pyqjeke/
Before reading:
total used free shared buff/cache available
Mem: 3945 1400 749 23 1796 2253
After reading:
total used free shared buff/cache available
Mem: 3945 1963 292 23 1690 1690
Sometime after:
total used free shared buff/cache available
Mem: 3945 1398 856 23 1690 2255
I'm using Firefox and Manjaro.
Edit
With Chromium these are my results.
Before:
total used free shared buff/cache available
Mem: 3945 1140 633 52 2171 2476
After loading pictures:
total used free shared buff/cache available
Mem: 3945 1573 296 43 2075 2050
And after that it wouldn't go down... so I'm guessing the GC is not releasing the file readers. So I did a very small change to the code:
http://jsfiddle.net/2pyqjeke/1/
And here are the results again in Chromium...
Before:
total used free shared buff/cache available
Mem: 3945 1197 672 44 2075 2426
After loading pictures:
total used free shared buff/cache available
Mem: 3945 1588 322 44 2034 2035
And after a while it went down to:
total used free shared buff/cache available
Mem: 3945 1227 684 44 2034 2397
Quite frankly I don't why Chromium is not releasing the FileReader and Firefox is.
来源:https://stackoverflow.com/questions/32102361/filereader-memory-leak