JavaScript内存泄漏

背景知识

背景知识可以参考:

导致内存泄漏的原因

1. 没有切断与 GC Root之间引用

因为没有完全切断与根节点之间的引用,导致GC无法回收。

具体原因:

  1. 滥用全局变量
a = "1234"

// 相当于

window.a = "1234"

很多无意义的变量如果都绑定在 window上,就无法被回收。

  1. DOM元素清空或者删除时,绑定事件未清除
<div id="myDiv">
    <input type="button" value="Click me" id="myBtn">
</div>

<script type="text/javascript">
    var btn = document.getElementById('myBtn');
    btn.onclick = function () {
        document.getElementById('myDiv').innerHTML = 'Processing...';
        /* 清除事件绑定 */
        // btn.onclick = null;
    };
</script>
  1. 滥用闭包

闭包不是一个内存泄漏的必然原因。

内存泄漏,是人为使用出来的。闭包的场景如果错误使用会引发内存泄漏。

<div id="myDiv">
    <input type="button" value="Click me" id="myBtn">
</div>

<script type="text/javascript">
    var btn = document.getElementById('myBtn');
    btn.onclick = function () {
        document.getElementById('myDiv').innerHTML = 'Processing...';
        /* 清除事件绑定 */
        // btn.onclick = null;
    };
</script>

DOM元素清空或删除时,子元素存在JS引用,导致子元素的所有父元素都不会被删除

// b是a的子dom节点, a是body的子节点
var aElement = document.getElementById("a");
var bElement = document.getElementById("b");
document.body.removeChild(aElement);
// aElement = null;
// bElement = null;
  1. 过渡占用内存

过大的数据占用内存。

var arr = [];
for (var i=0; i< 100000000000; i++) {
    var a = {
        'desc': 'an object'
    }
    arr.push(a);
}
  1. 循环引用

这个在引用计数实现的 GC 中会产生内存泄漏。标记清除已经克服了这个问题。

参考

Mark24

Everything can Mix.