js內(nèi)存泄露
js內(nèi)存的機制
- js的基本變量 boolean string number null undefined symbol 是分配在棧上的
- js的引用類型是分配在堆上面的
- 內(nèi)存泄露只會發(fā)生在對堆區(qū)
js內(nèi)存回收機制
js是用標(biāo)記清楚法出牧,部分Ie低版本使用引用計數(shù)法進(jìn)行垃圾回收
上面叫內(nèi)存泄露呢哭当?
內(nèi)存泄露就是 內(nèi)存泄漏是指我們已經(jīng)無法再通過js代碼來引用到某個對象,但垃圾回收器卻認(rèn)為這個對象還在被引用刽锤,因此在回收的時候不會釋放它 上面這句話就說成了內(nèi)存泄露的根本
下面分析一段內(nèi)存泄露的代碼
var demo = document.getElementById('demo');;
var username = {name: 'username'}; //在堆上面生成一個對象
demo.onclick = function() {
this.innerHTML = username.name; //這里面對username進(jìn)行引用
}
username = null; //username 置為空 var demo = document.getElementById('demo');;
var username = {name: 'username'}; //在堆上面生成一個對象
demo.onclick = function() {
this.innerHTML = username.name; //這里面對username進(jìn)行引用
}
username = null; //username 置為空
上面的代碼發(fā)送內(nèi)存泄露了么柜去?
確實是發(fā)生了塘砸, onclick函數(shù)里面引用username, js解析器會標(biāo)記這個堆地址在onclick里面會有引用足淆, 雖然最后我們設(shè)置username = null, onclick里面的標(biāo)記并沒有清楚尝胆,即我們無法通過代碼進(jìn)行引用到之前創(chuàng)建的username對應(yīng)的堆的這個地址丧裁,也無法清楚js解析器標(biāo)記的,onclick里面對這個堆地址的引用含衔。所以發(fā)生內(nèi)存泄露
那如何才能避免發(fā)生這樣情況呢煎娇? 有兩種,一種是保證 這個堆地址能被我們js代碼控制贪染,另外一個的話缓呛,由于是onclick發(fā)生泄露,所以我們可以 設(shè)置 onclick = null
再來看另外一個情況
function bindEvent()
{
var obj = document.createElement("XXX");
obj.onclick = function(){
// ...
}
}
bindEvent();
上面的發(fā)送泄露了么杭隙? 發(fā)生了哟绊,注意是這個dom上面的onclick函數(shù)比較特殊,它會把
onclick函數(shù)注冊到外面去寺渗,相當(dāng)于閉包暴露在外面了匿情,所以bindEvent會創(chuàng)建一個閉包,而且對于里面生成的的obj信殊,我們是無法引用的到的炬称,所以發(fā)生了內(nèi)存泄露