Mark24
记录灵感、技术、思考
JavaScript内存泄漏
背景知识
背景知识可以参考:
导致内存泄漏的原因
1. 没有切断与 GC Root之间引用
因为没有完全切断与根节点之间的引用,导致GC无法回收。
具体原因:
- 滥用全局变量
a = "1234"
// 相当于
window.a = "1234"
很多无意义的变量如果都绑定在 window
上,就无法被回收。
- 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>
- 滥用闭包
闭包不是一个内存泄漏的必然原因。
内存泄漏,是人为使用出来的。闭包的场景如果错误使用会引发内存泄漏。
<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;
- 过渡占用内存
过大的数据占用内存。
var arr = [];
for (var i=0; i< 100000000000; i++) {
var a = {
'desc': 'an object'
}
arr.push(a);
}
- 循环引用
这个在引用计数实现的 GC 中会产生内存泄漏。标记清除已经克服了这个问题。