在JavaScript中,由于編碼者忽略或者不注意某些細(xì)節(jié)拳恋,經(jīng)常會(huì)造成內(nèi)存泄露凡资。
首先,什么是內(nèi)存泄漏谬运?這是個(gè)什么東西隙赁?
? ? ? 內(nèi)存泄露是指分配給應(yīng)用的內(nèi)存不能被重新分配,即使在內(nèi)存已經(jīng)不被使用的時(shí)候梆暖。正常情況下伞访,垃圾回收器在 DOM 元素和 event 處理器不被引用或訪問(wèn)的時(shí)候回收它們。但是轰驳,IE 的早些版本(IE7和之前)中內(nèi)存泄露是很容易出現(xiàn)的厚掷,因?yàn)閮?nèi)存管理器不能正確理解 Javascript 生命周期而且在周期被打破(可以通過(guò)賦值為 null 實(shí)現(xiàn))前不會(huì)回收內(nèi)存级解。內(nèi)存泄露會(huì)降低 Web 應(yīng)用程序的性能冒黑,直到浪費(fèi)的內(nèi)存超過(guò)了系統(tǒng)所能分配的,應(yīng)用程序?qū)⒉荒苁褂谩?br>
這個(gè)東西很可怕蠕趁,怎樣造成了這樣子薛闪?
1) 循環(huán)引用
? ? ? ?一個(gè)很簡(jiǎn)單的例子:一個(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诱咏。
2) Javascript 閉包
? ? ? ?閉包可以導(dǎo)致內(nèi)存泄露是因?yàn)閮?nèi)部方法保持一個(gè)對(duì)外部方法變量的引用,所以盡管方法返回了缴挖,內(nèi)部方法還可以繼續(xù)訪問(wèn)在外部方法中定義的私有變量袋狞。對(duì) Javascript 程序員來(lái)說(shuō)最好的做法是在頁(yè)面重載前斷開(kāi)所有的事件處理器。
3) DOM 插入順序
? ? ? ?當(dāng) 2 個(gè)不同范圍的 DOM?對(duì)象附加到一起的時(shí)候,一個(gè)臨時(shí)的對(duì)象會(huì)被創(chuàng)建苟鸯。這個(gè) DOM 對(duì)象改變范圍到 document 時(shí)同蜻,那個(gè)臨時(shí)對(duì)象就沒(méi)用了。也就是說(shuō)早处, DOM?對(duì)象應(yīng)該按照從當(dāng)前頁(yè)面存在的最上面的 DOM?元素開(kāi)始往下直到剩下的 DOM?元素的順序添加湾蔓,這樣它們就總是有同樣的范圍,不會(huì)產(chǎn)生臨時(shí)對(duì)象砌梆。
垃圾回收
? ? ? javascript是一門(mén)具有自動(dòng)垃圾收集機(jī)制的編程語(yǔ)言默责,執(zhí)行環(huán)境會(huì)負(fù)責(zé)管理代碼執(zhí)行過(guò)程中使用的內(nèi)存,人為不用管咸包。這種機(jī)制就是:找出那些補(bǔ)在繼續(xù)使用的變量桃序,然后釋放其占用的內(nèi)存。所以烂瘫,垃圾收集器會(huì)按照固定的時(shí)間間隔媒熊,周期性地執(zhí)行這一操作。
方法:標(biāo)記清除忱反,給當(dāng)前不使用的值加上標(biāo)記泛释,然后將其回收。另一種就是“引用計(jì)數(shù)“温算,跟蹤記錄所有的值被引用的次數(shù)怜校。