垃圾回收:JavaScript代碼運(yùn)行時(shí),需要分配內(nèi)存空間來(lái)儲(chǔ)存變量和值。當(dāng)變量不在參與運(yùn)行時(shí),就需要系統(tǒng)收回被占用的內(nèi)存空間,這就是垃圾回收。
回收機(jī)制:Javascript 具有自動(dòng)垃圾回收機(jī)制,會(huì)定期對(duì)那些不再使用的變量、對(duì)象所占用的內(nèi)存進(jìn)行釋放,原理就是找到不再使用的變量,然后釋放掉其占用的內(nèi)存。
JavaScript中存在兩種變量:局部變量和全局變量。全局變量的生命周期會(huì)持續(xù)要頁(yè)面卸載;而局部變量聲明在函數(shù)中,它的生命周期從函數(shù)執(zhí)行開(kāi)始,直到函數(shù)執(zhí)行結(jié)束,在這個(gè)過(guò)程中,局部變量會(huì)在堆或棧中存儲(chǔ)它們的值,當(dāng)函數(shù)執(zhí)行結(jié)束后,這些局部變量不再被使用,它們所占有的空間就會(huì)被釋放。
不過(guò),當(dāng)局部變量被外部函數(shù)使用時(shí),其中一種情況就是閉包,在函數(shù)執(zhí)行結(jié)束后,函數(shù)外部的變量依然指向函數(shù)內(nèi)部的局部變量,此時(shí)局部變量依然在被使用,所以不會(huì)回收。
(2)垃圾回收的方式
瀏覽器通常使用的垃圾回收方法有兩種:標(biāo)記清除,引用計(jì)數(shù)。
1)標(biāo)記清除
標(biāo)記清除是瀏覽器常見(jiàn)的垃圾回收方式,當(dāng)變量進(jìn)入執(zhí)行環(huán)境時(shí),就標(biāo)記這個(gè)變量“進(jìn)入環(huán)境”,被標(biāo)記為“進(jìn)入環(huán)境”的變量是不能被回收的,因?yàn)樗麄冋诒皇褂谩.?dāng)變量離開(kāi)環(huán)境時(shí),就會(huì)被標(biāo)記為“離開(kāi)環(huán)境”,被標(biāo)記為“離開(kāi)環(huán)境”的變量會(huì)被內(nèi)存釋放。
垃圾收集器在運(yùn)行的時(shí)候會(huì)給存儲(chǔ)在內(nèi)存中的所有變量都加上標(biāo)記。然后,它會(huì)去掉環(huán)境中的變量以及被環(huán)境中的變量引用的標(biāo)記。而在此之后再被加上標(biāo)記的變量將被視為準(zhǔn)備刪除的變量,原因是環(huán)境中的變量已經(jīng)無(wú)法訪(fǎng)問(wèn)到這些變量了。最后。垃圾收集器完成內(nèi)存清除工作,銷(xiāo)毀那些帶標(biāo)記的值,并回收他們所占用的內(nèi)存空間。
2)引用計(jì)數(shù)
另外一種垃圾回收機(jī)制就是引用計(jì)數(shù),這個(gè)用的相對(duì)較少。引用計(jì)數(shù)就是跟蹤記錄每個(gè)值被引用的次數(shù)。當(dāng)聲明了一個(gè)變量并將一個(gè)引用類(lèi)型賦值給該變量時(shí),則這個(gè)值的引用次數(shù)就是1。相反,如果包含對(duì)這個(gè)值引用的變量又取得了另外一個(gè)值,則這個(gè)值的引用次數(shù)就減1。當(dāng)這個(gè)引用次數(shù)變?yōu)?時(shí),說(shuō)明這個(gè)變量已經(jīng)沒(méi)有價(jià)值,因此,在在機(jī)回收期下次再運(yùn)行時(shí),這個(gè)變量所占有的內(nèi)存空間就會(huì)被釋放出來(lái)。
這種方法會(huì)引起循環(huán)引用的問(wèn)題:例如: obj1和obj2通過(guò)屬性進(jìn)行相互引用,兩個(gè)對(duì)象的引用次數(shù)都是2。當(dāng)使用循環(huán)計(jì)數(shù)時(shí),由于函數(shù)執(zhí)行完后,兩個(gè)對(duì)象都離開(kāi)作用域,函數(shù)執(zhí)行結(jié)束,obj1和obj2還將會(huì)繼續(xù)存在,因此它們的引用次數(shù)永遠(yuǎn)不會(huì)是0,就會(huì)引起循環(huán)引用。
這種情況下,就要手動(dòng)釋放變量占用的內(nèi)存:
(3)減少垃圾回收
雖然瀏覽器可以進(jìn)行垃圾自動(dòng)回收,但是當(dāng)代碼比較復(fù)雜時(shí),垃圾回收所帶來(lái)的代價(jià)比較大,所以應(yīng)該盡量減少垃圾回收。
對(duì)數(shù)組進(jìn)行優(yōu)化: 在清空一個(gè)數(shù)組時(shí),最簡(jiǎn)單的方法就是給其賦值為[ ],但是與此同時(shí)會(huì)創(chuàng)建一個(gè)新的空對(duì)象,可以將數(shù)組的長(zhǎng)度設(shè)置為0,以此來(lái)達(dá)到清空數(shù)組的目的。
對(duì)object進(jìn)行優(yōu)化: 對(duì)象盡量復(fù)用,對(duì)于不再使用的對(duì)象,就將其設(shè)置為null,盡快被回收。
對(duì)函數(shù)進(jìn)行優(yōu)化: 在循環(huán)中的函數(shù)表達(dá)式,如果可以復(fù)用,盡量放在函數(shù)的外面。