继续这个问题:Task manager shows memory leak, but Heap snapshot doesn't
我设法创建了一个非常简单的例子,它说明了这个漏洞,这里是完整的源代码:
<!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>
如果我运行此脚本,Chrome会继续占用内存,直至崩溃。其他浏览器没有。我没有逐个删除孩子,而是试图通过设置innerHTML =“”来快速清除它,但它是一样的。
我启用了Chrome的实验性功能,显示了使用的内存类型。 “页面结构”内存增加了一点(但是HTML保持不变并且没有分离的DOM对象),但是大多数内存都转到“其他”部分。
如果我停止脚本并强制GC完成它的工作,内存只减少几千字节。但是,如果我等待一两分钟,内存几乎会被清理到初始级别。我知道我的剧本非常激烈,但如果我每隔1秒或2秒运行一次就会发生这种情况 - 我认为这足以让GC做到这一点。我知道GC正在发挥作用,因为其他类型的内存已经发布。这可能是Chrome的错误吗?也许我应该在删除元素之前做些什么?
答案 0 :(得分:1)
我设法放慢速度,但仍然在泄漏。我还使用没有泄漏的Raphael.js重新创建了测试。但是当我进行测试时,我发现它是在追加圈子的时候。所以拉斐尔必须采取措施阻止它在那时泄漏。
答案 1 :(得分:0)
不确定,如果它会有很大帮助,但如果你只定义一次“var svg”, 然后内存消耗(在任务管理器中)没有快速上升 并且在此之后stop()函数也能正常工作
答案 2 :(得分:0)