JS垃圾回收
基本思路:確定那個(gè)變量不會(huì)再使用,然后釋放其所占內(nèi)存,這個(gè)過(guò)程是周期性的,即垃圾回收程序每隔一段時(shí)間(或者說(shuō)在代碼執(zhí)行過(guò)程中某個(gè)預(yù)定的收集時(shí)間)就會(huì)自動(dòng)運(yùn)行
- 缺點(diǎn):垃圾回收的過(guò)程中,因?yàn)槟硥K內(nèi)存是否還有用,不可判定
栗子:
函數(shù)中的局部變量會(huì)在函數(shù)執(zhí)行時(shí)存在,此時(shí),棧(或堆)內(nèi)存會(huì)分配空間以保存相應(yīng)的值
函數(shù)在內(nèi)部使用了變量,然后退出,此時(shí)就不再需要哪個(gè)局部變量了,他占用的內(nèi)容就會(huì)被釋放,供后面變量使用
這種情況下顯然不再需要局部變量了,但并不是所有的時(shí)候都會(huì)這么明顯,這個(gè)局部變量不再需要使用
兩種標(biāo)記方法
垃圾回收程序必須跟蹤記錄那個(gè)變量還會(huì)使用,以及那個(gè)變量不需要再使用,以便回收內(nèi)存.
1)標(biāo)記清理 (常用)
當(dāng)變量進(jìn)入執(zhí)行上下文時(shí),就會(huì)被執(zhí)行上下文的文本環(huán)境記錄(此時(shí),加上存在于執(zhí)行上下文的標(biāo)記),當(dāng)變量離開(kāi)執(zhí)行上下文時(shí)也會(huì)被加上離開(kāi)執(zhí)行上下文的標(biāo)記
標(biāo)記的方法有很多
2)引用計(jì)數(shù)
思路:每個(gè)值都被記錄他引用的次數(shù),當(dāng)這個(gè)值聲明變量時(shí)并給他賦予一個(gè)引用值,如果同一個(gè)值又被賦予另一個(gè)變量時(shí),引用值++,反之這個(gè)值引用的變量被其他值覆蓋時(shí),引用值--,當(dāng)其引用值為 0 時(shí) 釋放該值所占的內(nèi)存 以供其他人使用(這個(gè)內(nèi)存RAM => 運(yùn)行內(nèi)存)
var num = 1
// 內(nèi)存中會(huì)有一個(gè) 1 的值 并且其 引用值 n = 1
var nums = 1
// 此時(shí) 內(nèi)存 中的 1 的 引用值++ => n++ = 2
num = 2
// 此時(shí) 內(nèi)存 中的 1 的 引用值-- => n-- = 1 而 2 的引用值 s = 1
nums = 2
// 此時(shí) 內(nèi)存 中的 1 的 引用值-- => n-- = 0 而 2 的引用值 s++ = 1
// 故 此時(shí) 值:1 所占用的內(nèi)存 將被釋放
在NetScape 4.0 版本時(shí) JavaScript就放棄了 引用計(jì)數(shù) 轉(zhuǎn)而 使用 標(biāo)記清理 因?yàn)楹瘮?shù)中的Object 的 引用值 永遠(yuǎn)不會(huì)為 0 導(dǎo)致內(nèi)存占用無(wú)法被釋放 從而導(dǎo)致 性能降低