只需添加和删除SVG元素,Chrome就会泄漏内存

时间:2013-01-25 09:43:29

标签: javascript memory-leaks svg

继续这个问题: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的错误吗?也许我应该在删除元素之前做些什么?

3 个答案:

答案 0 :(得分:1)

我设法放慢速度,但仍然在泄漏。我还使用没有泄漏的Raphael.js重新创建了测试。但是当我进行测试时,我发现它是在追加圈子的时候。所以拉斐尔必须采取措施阻止它在那时泄漏。

答案 1 :(得分:0)

不确定,如果它会有很大帮助,但如果你只定义一次“var svg”,  然后内存消耗(在任务管理器中)没有快速上升  并且在此之后stop()函数也能正常工作

答案 2 :(得分:0)