Reputation: 6025
Continuing this question: Task manager shows memory leak, but Heap snapshot doesn't
I managed to create a very simple example, which illustrates this leak, here is full source code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>svg test</title>
<script type="text/javascript">
var svg;
var interval;
var svg;
window.onload = function(){
createSVG();
start();
}
function start(){
interval = setInterval(createElements, 100);
}
function createSVG(){
var div = document.getElementById("svgdiv");
div.innerHTML = "";
svg = createSvgElement("svg");
svg.style.position = "absolute";
svg.style.width = "600px";
svg.style.height = "500px";
svg.setAttribute("version", "1.1");
div.appendChild(svg);
createElements();
}
function createElements(){
removeElements();
for(var i = 0; i < 500; i++){
var element = createSvgElement("circle");
element.setAttribute("r", Math.random() * 10);
var transform = "translate(" + Math.round(Math.random() * 600) + "," + Math.round(Math.random() * 500) + ")";
element.setAttribute("transform", transform);
element.setAttribute("fill", "#CC0000");
svg.appendChild(element);
}
}
function removeElements(){
while(svg.hasChildNodes() ){
svg.removeChild(svg.lastChild);
}
}
function createSvgElement (name) {
return document.createElementNS("http://www.w3.org/2000/svg", name);
}
function stop(){
clearInterval(interval)
}
</script>
</head>
<body style="background-color:#FFFFFF">
<div id="svgdiv" style="width:600px; height:500px;"></div>
<input type="button" value="start" onclick="start()">
<input type="button" value="stop" onclick="stop()">
</body>
</html>
If I run this script, Chrome keeps eating the memory until it crashes. Other browsers don't. Instead of removing children one by one I also tried to clear it in a fast way by setting innerHTML="", but it's the same.
I enabled an experimental feature of Chrome which shows the kind of memory is used. The "Pages structures" memory is increasing a bit (however the HTML remains the same and there are no detached DOM objects), but the most memory goes to "Other" section.
If I stop the script and force GC to do it's job, the memory decreases by only few kilobytes. However if I wait for a minute or two, the memory is cleaned almost to a initial level. I know that my script is quite intense, but this happens also if I run it every 1 or two seconds only - I think that's quite enough for GC to do it's job. And I know GC is working, as other kind of memory is released. Could this be a Chrome bug? Maybe I should do something before removing the elements?
Upvotes: 7
Views: 3710
Reputation: 6025
This was indeed bug in Chrome, which was fixed some time later: https://bugs.chromium.org/p/chromium/issues/detail?id=172221&can=4&q=svg&colspec=ID%20Pri%20Mstone%20ReleaseBlock%20OS%20Area%20Feature%20Status%20Owner%20Summary
Upvotes: 0
Reputation: 1770
Not sure, if it would be of much help, but if you define "var svg" only once, then memory-consumption ( in Task manager) is not rising that fast and also stop() function does work after that
Upvotes: 0
Reputation: 615
I managed to slow it down but it is still leaking. I also recreated the test using Raphael.js which did not leak. But when I was testing I found that it was when it was appending the circles. So Raphael must be doing something to stop it from leaking at that point.
Upvotes: 1