7

この質問の続き:タスクマネージャーはメモリリークを表示しますが、ヒープスナップショットは表示しません

私はこのリークを説明する非常に簡単な例を作成することができました。完全なソースコードは次のとおりです。

<!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はクラッシュするまでメモリを消費し続けます。他のブラウザはそうではありません。子を1つずつ削除する代わりに、innerHTML = ""を設定することで、すばやくクリアしようとしましたが、同じです。

使用されているメモリの種類を示すChromeの実験的な機能を有効にしました。「ページ構造」のメモリは少し増えていますが(ただし、HTMLは同じままで、切り離されたDOMオブジェクトはありません)、ほとんどのメモリは「その他」セクションに移動します。

スクリプトを停止してGCにその仕事を強制すると、メモリはわずか数キロバイト減少します。ただし、1〜2分待つと、メモリはほぼ初期レベルまでクリーンアップされます。私のスクリプトは非常に強力であることを知っていますが、これは1秒または2秒ごとに実行した場合にも発生します。これは、GCがその仕事をするのに十分だと思います。そして、他の種類のメモリが解放されるので、GCが機能していることを私は知っています。これはChromeのバグでしょうか?たぶん私は要素を削除する前に何かをする必要がありますか?

4

3 に答える 3

1

なんとか速度を落としましたが、まだ漏れています。また、リークしなかった Raphael.js を使用してテストを再作成しました。しかし、私がテストしていたとき、円を追加していたときであることがわかりました。だから、ラファエルはその時点で漏れを止めるために何かをしているに違いない.

于 2013-01-25T10:59:46.467 に答える
0

それが大いに役立つかどうかはわかりませんが、「var svg」を一度だけ定義すると、(タスクマネージャーの)メモリ消費量はそれほど速く上昇せず、その後stop()関数も機能します

于 2013-01-25T12:42:50.580 に答える
0

これは確かに Chrome のバグであり、しばらくして修正されました : 20Area%20Feature%20Status%20Owner%20Summary

于 2016-07-06T19:05:47.397 に答える