什么是內(nèi)存泄露?
內(nèi)存泄露是指一塊被分配的內(nèi)存既不能使用,又不能回收,直到瀏覽器進(jìn)程結(jié)束。在C++中,因?yàn)槭鞘謩?dòng)管理內(nèi)存,內(nèi)存泄露是經(jīng)常出現(xiàn)的事情。而現(xiàn)在流行的C#和Java等語(yǔ)言采用了自動(dòng)垃圾回收方法管理內(nèi)存,正常使用的情況下幾乎不會(huì)發(fā)生內(nèi)存泄露。瀏覽器中也是采用自動(dòng)垃圾回收方法管理內(nèi)存,但由于瀏覽器垃圾回收方法有bug,會(huì)產(chǎn)生內(nèi)存泄露。
常見(jiàn)內(nèi)存泄露的幾種情況
1.循環(huán)引用 2.Javascript閉包 3.DOM插入
一個(gè)DOM對(duì)象被一個(gè)Javascript對(duì)象引用,與此同時(shí)又引用同一個(gè)或其它的Javascript對(duì)象,這個(gè)DOM對(duì)象可能會(huì)引發(fā)內(nèi)存泄漏。這個(gè)DOM對(duì)象的引用將不會(huì)在腳本停止的時(shí)候被垃圾回收器回收。要想破壞循環(huán)引用,引用DOM元素的對(duì)象或DOM對(duì)象的引用需要被賦值為null。
其實(shí)絕大部分內(nèi)存泄漏都不是由Javascript引起的,瀏覽器的回收機(jī)制已經(jīng)做的相當(dāng)好了,多數(shù)的泄漏都是由于與DOM交互而產(chǎn)生的。
含有DOM對(duì)象的循環(huán)引用將導(dǎo)致大部分當(dāng)前主流瀏覽器內(nèi)存泄露
第一種:多個(gè)對(duì)象循環(huán)引用
var a=new Object; var b=new Object; a.r=b; b.r=a;
第二種:循環(huán)引用自己
var a=new Object; a.r=a;
循環(huán)引用很常見(jiàn)且大部分情況下是無(wú)害的,但當(dāng)參與循環(huán)引用的對(duì)象中有DOM對(duì)象或者ActiveX對(duì)象時(shí),循環(huán)引用將導(dǎo)致內(nèi)存泄露。
我們把例子中的任何一個(gè)new Object替換成document.getElementById或者document.createElement就會(huì)發(fā)生內(nèi)存泄露了。
所以這里的總結(jié):
? JS的內(nèi)存泄露,無(wú)怪乎就是從DOM中remove了元素,但是依然有變量或者對(duì)象引用了該DOM對(duì)象。然后內(nèi)存中無(wú)法刪除。使得瀏覽器的內(nèi)存占用居高不下。這種內(nèi)存占用,隨著瀏覽器的刷新,會(huì)自動(dòng)釋放。
? 而另外一種情況,就是循環(huán)引用,一個(gè)DOM對(duì)象和JS對(duì)象之間互相引用,這樣造成的情況更嚴(yán)重一些,即使刷新,內(nèi)存也不會(huì)減少。這就是嚴(yán)格意義上說(shuō)的內(nèi)存泄露了。
所以在平時(shí)實(shí)際應(yīng)用中, 我們經(jīng)常需要給元素緩存一些數(shù)據(jù),并且這些數(shù)據(jù)往往和DOM元素緊密相關(guān)。由于DOM元素(節(jié)點(diǎn))也是對(duì)象, 所以我們可以直接擴(kuò)展DOM元素的屬性,但是如果給DOM元素添加自定義的屬性和過(guò)多的數(shù)據(jù)可能會(huì)引起內(nèi)存泄漏,所以應(yīng)該要盡量避免這樣做。 因此更好的解決方法是使用一種低耦合的方式讓DOM和緩存數(shù)據(jù)能夠聯(lián)系起來(lái)。
所以我們必須有一種機(jī)制,避免引用數(shù)據(jù)直接依附在DOM對(duì)象上,這樣盡量避免內(nèi)存泄漏的產(chǎn)生。jQuery的緩存系統(tǒng)就很好的解決了這一問(wèn)題。
請(qǐng)驗(yàn)證,完成請(qǐng)求
由于請(qǐng)求次數(shù)過(guò)多,請(qǐng)先驗(yàn)證,完成再次請(qǐng)求
打開(kāi)微信掃碼自動(dòng)綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書(shū)簽
舉報(bào)