LoginSignup
88
89

More than 5 years have passed since last update.

javascriptのメモリリーク対策(随時更新)

Last updated at Posted at 2014-07-04

クロージャの安易な利用を避ける

最近のモダンなブラウザでは対策されているが、
それでもメモリリークは怖いので慎重に利用する。

典型的な悪い例

badSample.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
    <title>サンプル</title>
    <script type="text/javascript">
    function test() {
        var elt = document.getElementById('i0');
        elt.src = 't2.png';
        elt.onclick = function() {
            location.href = 't2.html'; 
        }
    }
    </script>
</head>
<body>
    <div><img id="i0" src="t1.png"></div>
    <div><input type="button" onclick="test()" value="Test"/></div>
</body>
</html>

クロージャによる循環参照を引き起こしてる。

function test() {
        var elt = document.getElementById('i0');
        elt.src = 't2.png';
        elt.onclick = function() {
            location.href = 't2.html'; 
        }
    }

メモリリークの間違った検証の仕方

この確かめ方はメモリリークという問題の主眼がわかっていない。

badTest.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
    <title>サンプル</title>
    <script type="text/javascript">
    function test() {
        var elt = document.getElementById('i0');
        elt.src = 't2.png';
        elt.onclick = function() {
            location.href = 't2.html'; 
        }
    }
    </script>
</head>
<body>
    <div><img id="i0" src="t1.png"></div>
    <div><input type="button" onclick="test()" value="Test"/></div>
</body>
</html>

メモリリークとは、別のページに遷移してもメモリが開放されない問題。
このコードは同じfunctionを何度も呼んで検証しているが、そもそもtest()の中では
メモリ食いまくるようなたいした処理をしてないのでメモリリークは微々たるもの。
言いたいのは、こんな書き方してるといつか痛い目見るぞって話。

痛い目を見た例

がんがんリークする。

memoryLeak.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
    <title>サンプル</title>
    <script type="text/javascript">
    function test() {
        var dummy = [];
        for(var i=0;i<100000;i++){
            dummy[i] = i; 
        }
        var elt = document.getElementById('i0');
        elt.src = 't2.png';
        elt.onclick = function() {
            location.href = 't2.html'; 
        }
    }
    </script>
</head>
<body>
    <div><img id="i0" src="t1.png"></div>
    <div><input type="button" onclick="test()" value="Test"/></div>
</body>
</html>

対応策

明示的にnullを代入して参照を切る。

bugfixSample.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
    <title>サンプル</title>
    <script type="text/javascript">
    function test() {
        var elt = document.getElementById('i0');
        elt.src = 't2.png';
        elt.onclick = function() {
            location.href = 't2.html'; 
        }
        elt = null;
    }
    </script>
</head>
<body>
    <div><img id="i0" src="t1.png"></div>
    <div><input type="button" onclick="test()" value="Test"/></div>
</body>
</html>

いちいちnull代入するのめんどいから他の手を探す(追記予定)
参考

88
89
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
88
89