测试
了解了垃圾回收的计数原理,就知道为啥闭包会形成内存泄漏了。看这样一个简单的例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">开关</button>
</body>
</html>
<script>
let btn = document.getElementById('btn');
btn.addEventListener('click', () => {
for (let i = 0; i < 100000; i++) {
outer();
}
}, false);
function outer() {
let bar = [];
function inner() {
console.log(`引用堆内存 ${bar}`);//对堆内存有引用,没有释放内存
}
}
</script>
多按几次按钮,录制一下内存的使用情况:
add.png
可以看到heap堆内存是一直飙升的,我们只需将inner()函数的console注释掉,内存就可以降下来了:
ok.png
闭包原理
闭包的原理很简单,就是关于堆内存是否释放的问题。
然后函数执行完毕,在函数作用域中的bar变量释放,引用计数变为1,此时是无法释放掉堆内存的: 2.png
如果inner函数没有对堆内存的引用,此时引用计数为0,堆内存可以回收: 3.png
网友评论