接上回我写了一篇关于闭包的博客《进修JavaScript之闭包》, 末了谈到闭包致使的题目时留了一个尾:
在IE9以下的浏览器中会有内存走漏的题目。
本日的博客就继承探究一下内存走漏的题目。
浅谈JavaScript渣滓接纳机制
1.标记消灭
一开始渣滓收集器会给内存中的一切变量做一个标记,以后当顺序运转进入响应的环境时,会去掉环境中的变量和被环境中变量援用的变量标记;当退出该环境后,没法再被接见的变量又从新被标记,这些被从新标记的变量就会被渣滓收集器接纳。
2.援用计数
纪录每一个值被援用的次数,当被援用次数为0时该值才会被接纳。假如某个值被其他对象援用(赋给某个变量),援用次数+1;假如不再被援用则-1。
闭包致使的内存走漏怎样发生的
在IE9之前的浏览器中,DOM对象的渣滓接纳机制就是运用援用计数(虽然JS引擎是用标记消灭),因而一旦发生轮回援用(比方下面这个例子)内存就会一向被占用而没法接纳。
function a () {
var div = document.getElementById('myTitle')
div.onclick = function () {
alert(div.id)
}
}
这段代码中变量div中保留了一个HTML元素对象,又创建了一个事宜处置惩罚顺序,个中还直接援用了div.id形成了轮回援用,而且这个匿名函数只需存在就可以应用闭包的特征接见到div,因而这个HTML元素的援用至少是1。
怎样处理内存走漏的题目
首先要消除轮回援用:把div.id赋值给一个变量,然后在匿名函数中援用该变量,因为变量只包括值而不存在对div直接援用,所以消除了轮回援用。然则,因为闭包的特征使得其仍保留着a函数的运动对象(即是间接地在援用HTML元素),因而还需要手动消除div对HTML元素的援用。用代码写出来就是:
function a () {
var div = document.getElementById('myTitle')
var id = div.id // 消除轮回援用
div.onclick = function () {
alert(id)
}
div = null // 手动消除闭包对外部函数运动对象的援用
}
如许DOM对象的援用就变成了0,也就会被一般地接纳了。
博客地址:lbj的前端之路
原文链接:进修JavaScript之内存走漏