Reputation: 198388
I have a simple html/javascript code, which will create some DOM then remove them.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</head>
<body>
<button onclick="create()"> Create </button>
<button onclick="clearContainer()"> Clear </button>
<div id="container"></div>
</body>
</html>
<script>
function create() {
var c = $("#container");
for(var i = 0;i<10000; i++){
c.append("<li>Hellosd fssd f df sdf f f wef ewf we fwe f wef ewf wef ew few f ewf wf ewf wef </li>");
}
}
function clearContainer() {
var c = $("#container");
c.empty();
}
</script>
There will be a Create
button and a Clear
button. When I click on the create button, it will append 10000 li
element to the container div, and when I click on the clear button, it will remove them.
When I try it on chrome, the chrome process has an initial memory usage about 30M, it grows to 70M after I clicking on the create button several times, and when I click on clear button, it becomes 50M. It's 20M more than initial.
Then I try it on IE8, the IE process has an initial memory usage about 30M, it grows to more than 100M after I clicking on the create button only once, and when I click on clear button, it becomes 80M. It's 50M more than initial.
Is the code has memory leak? How to fix it?
Upvotes: 3
Views: 426
Reputation: 1075567
Is the code has memory leak?
No. The browsers are just keeping some of the memory they allocated in case they need to reuse it, and/or haven't (yet) garbage collected the objects that are no longer referenced. Because you've released all of your references to the list item elements (via jQuery's empty
call), it's down to the browser to actually let them go.
Of course, this answer assumes there are no bugs in the jQuery functions you're calling causing memory leaks (in particular the one that creates the li
elements). It's probably a reasonable assumption, although of course every once in a while even a well-respected library can have errors. If one of jQuery's common functions (that includes element construction) has a significant memory leak in a given version, it's likely to get found, reported, and fixed within a reasonable time, given the number of people using the library and the engaged team behind it.
And we're also assuming that there are no bugs in the browser's handling of the DOM manipulations causing memory leaks, which is a much less certain assumption. (Historically, browsers [regardless of the flavor] have had all sorts of issues with memory leaks; I don't think any browser has been immune.)
But there's no leak in your code, if you see what I mean.
Upvotes: 7
Reputation: 382454
By testing on Chromium/linux, I reliably reproduce your leak : each create/clear cycle makes the memory grow by 5MB to 10 MB, and this memory doesn't seem to be released.
I noted that it's possible to avoid the leak by slightly changing the clear function to replace the parent element instead of emptying it :
function clearContainer() {
var c = $("#container");
c.remove();
$('<ul id="container"></ul>').appendTo(document.body);
}
With this code, the memory comes back to the same level after each create/clear cycle.
I don't think the problem is in jQuery, but more probably in the browser's DOM objects as Firefox doesn't seem to have the same problem.
EDIT :
By automating the tests to push it farther, I could see the memory finally decreasing (I topped about 150 MB for the tab then could come back to 70 MB). The way the memory is managed here clearly is greedy but there's no real memory leak. As the memory consumption can be so different, I'd recommend you to remove the parent element instead of clearing it but this won't prevent any crash as a memory crash seems unlikely.
Upvotes: 4