Why this code is consuming memory and it is not get fully reclaimed?
I has a simple JavaScript code which is consuming memory while running infinitely. Memory consumption 开发者_Python百科is monitored by Google Chrome internal memory profiler.
setInterval(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', 'json.txt', true);
xhr.onreadystatechange = function() {
if(this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
}
};
xhr.send('');
}, 500);
Html file with above code sample and json.txt
is hosted on on my local server, getting a file isn't taking more than 500ms (it is always about 7-10ms).
In a long time run the memory graph is looks like that
EDIT The same Chrome window after a hour of work
EDIT On the long run (hours) not all memory is reclaimed an graph is still ascending. I understand why the memory is consumed, i didn't understand why it is not fully reclaimed.
EDIT This is how i can reduce memory leak
var callback = function(){
if(this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
}
}
setInterval(function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', 'json.txt', true);
xhr.onreadystatechange = callback;
xhr.send('');
}, 500);
This improvement allowing not to link callback's closure to xhr
var.
For one you repeatedly load the content of json.txt
, which will need some memory. Apart from that the XHR itself might need some memory as well. I don't see it as much of a problem, however, since the memory seems to get reclaimed anyway.
I imagine this interval isn't being set in a vacuum. The the function you're passing into setInterval may have access to the lexical scope it was defined in. This means every variable around it will always be reachable in the garbage collector's eyes, even if you're not using those variables within the function. The garbage collector will never clean it up. It might be better to define the function in a more sanitary environment where it wont have closure access to any variables large in size.
EDIT: Sorry, I'll try to make myself more clear. This has nothing to do with the XHR - you could put anything (or even nothing) in that setInterval function and it would still leak if there's some variables in its lexical scope that you would want cleaned up. You just need to make sure the setInterval function doesn't have closure access to any variables you want cleaned up. For example:
(function() {
var a = readFile('a-very-big-file.txt');
setInterval(function() {
console.log('im leaking!');
}, 500);
})();
That will leak. Even though the setInterval doesn't do anything particularly meaningful, it still has access to "a", and the garbage collector sees it as reachable.
Why shouldn't it? At least var xhr = new XMLHttpRequest(); must consume memory on each iteration and collected by GC (probably, it's seen on your chart).
If the request-response cycle takes longer than the specified interval there certainly will be some memory overhead.
Since memory will be freed only after a request has completed(Success or Error).
The memory is not being fully reclaimed most likely due to the use of console.log. I assume that under the hood, console will add things to the internal array, or maybe a string, and since you are adding large chunks of data to it, and never remove from it, GC will never clean it up, while the application is running. Try commenting out that statement and see if it changes memory usage. Memory that is used for creating XMLHttpRequest is eventually freed by GC, since the reference to it will become orphaned after the request is complete, but console is a global variable, that still stays in the scope while the page is available.
精彩评论