摘要:另一種垃圾收集算法是引用計(jì)數(shù),這種算法的思想是跟蹤記錄所有值被引用的次數(shù)。當(dāng)代碼中存在循環(huán)引用現(xiàn)象時(shí),引用計(jì)數(shù)算法就會(huì)導(dǎo)致問(wèn)題。
垃圾回收
javascript不同于c、c++的一個(gè)特點(diǎn)是:具有自動(dòng)的垃圾回收機(jī)制,這就意味著,開發(fā)人員可以專注于業(yè)務(wù),而不必把過(guò)多精力放在內(nèi)存的管理上,提高開發(fā)效率。
所謂的垃圾回收就是找出那些不再繼續(xù)使用的變量,然后釋放其占用的內(nèi)存。為此,垃圾收集器會(huì)按照固定的時(shí)間間隔(或代碼執(zhí)行中預(yù)定的收集時(shí)間),周期性地執(zhí)行這一操作。
目前在瀏覽器中,實(shí)現(xiàn)垃圾回收的方式主要有兩種:
1.標(biāo)記清除
也是javascript最常用的垃圾回收的方式。
在標(biāo)記清除的方式中有兩個(gè)概念:『進(jìn)入環(huán)境』和『離開環(huán)境』。『進(jìn)入環(huán)境』指變量進(jìn)入執(zhí)行的環(huán)境。『離開環(huán)境』指變量完成任務(wù),離開了執(zhí)行的環(huán)境。
垃圾收集器在運(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ú)法訪問(wèn)到這些變量了。最后,垃圾收集器完成內(nèi)存清除工作,銷毀那些帶標(biāo)記的值并回收它們所占用的內(nèi)存空間。
2.引用計(jì)數(shù)
引用計(jì)數(shù)的含義是跟蹤記錄每個(gè)值被引用的次數(shù)。當(dāng)聲明了一個(gè)變量并將一個(gè)引用類型值賦給該變量時(shí),則這個(gè)值的引用次數(shù)就是1。如果同一個(gè)值又被賦給另一個(gè)變量,則該值的引用次數(shù)加 1。相反,如果包含對(duì)這個(gè)值引用的變量又取得了另外一個(gè)值,則這個(gè)值的引用次數(shù)減 1。當(dāng)這個(gè)值的引用次數(shù)變成 0 時(shí),則說(shuō)明沒(méi)有辦法再訪問(wèn)這 個(gè)值了,因而就可以將其占用的內(nèi)存空間回收回來(lái)。這樣,當(dāng)垃圾收集器下次再運(yùn)行時(shí),它就會(huì)釋放那 些引用次數(shù)為零的值所占用的內(nèi)存。
這種機(jī)制其實(shí)在js中并不常用,因?yàn)檫@種機(jī)制會(huì)產(chǎn)生循環(huán)引用的問(wèn)題,『循環(huán)引用』指的是對(duì)象 A 中包含一個(gè)指向?qū)ο?B 的指針,而對(duì)象 B 中也包含一個(gè)指向?qū)ο?A 的引用。對(duì)于像js類的自動(dòng)回收機(jī)制的語(yǔ)言來(lái)說(shuō),需要額外手動(dòng)的去釋放內(nèi)存,其實(shí)并不友好。例如,在下面的例子中:
function garbage(){ var A = new Object(); var B = new Object(); A.property = B; B.property = A; }
由于對(duì)象A、B相互引用,引用次數(shù)都為2,所以其占用的內(nèi)存并不能被自動(dòng)釋放。
在IE的BOM和DOM中就采用了此類的引用計(jì)數(shù),在IE9以后,微軟轉(zhuǎn)而使用了標(biāo)記清除的方式來(lái)管理內(nèi)存,從而避免了兩種方式并存的局面。
由于瀏覽器和其他桌面程序相比,系統(tǒng)分配給瀏覽器的內(nèi)存相對(duì)較少,這樣做的目的主要是出于安全方面的考慮,防止運(yùn)行 JavaScript 的網(wǎng)頁(yè)耗盡全部系統(tǒng)內(nèi)存而導(dǎo)致系統(tǒng)崩潰。內(nèi)存限制問(wèn)題不僅會(huì)影響給變量分配內(nèi)存,同時(shí)還會(huì)影響調(diào)用棧以及在一個(gè)線程中能夠同時(shí)執(zhí)行的語(yǔ)句數(shù)量。
因此,確保占用最少的內(nèi)存可以讓頁(yè)面獲得更好的性能。而優(yōu)化內(nèi)存占用的最佳方式,就是為執(zhí)行中的代碼只保存必要的數(shù)據(jù)。一旦數(shù)據(jù)不再有用,最好通過(guò)將其值設(shè)置為 null 來(lái)釋放其引用——這個(gè)做法叫做解除引用(dereferencing)。這一做法適用于大多數(shù)全局變量和全局對(duì)象的屬性。局部變量會(huì)在它們離開執(zhí)行環(huán)境時(shí)自動(dòng)被解除引用。
function createPerson(name){ var localPerson = new Object(); localPerson.name = name; } var globalPerson = createPerson("Nicholas"); // 手工解除 globalPerson 的引用 globalPerson = null;
不過(guò),解除一個(gè)值的引用并不意味著自動(dòng)回收該值所占用的內(nèi)存。解除引用的真正作用是讓值脫離 執(zhí)行環(huán)境,以便垃圾收集器下次運(yùn)行時(shí)將其回收。
小結(jié)JavaScript 是一門具有自動(dòng)垃圾收集機(jī)制的編程語(yǔ)言,開發(fā)人員不必關(guān)心內(nèi)存分配和回收問(wèn)題。可 以對(duì) JavaScript 的垃圾收集例程作如下總結(jié)。
? 離開作用域的值將被自動(dòng)標(biāo)記為可以回收,因此將在垃圾收集期間被刪除。
? “標(biāo)記清除”是目前主流的垃圾收集算法,這種算法的思想是給當(dāng)前不使用的值加上標(biāo)記,然
后再回收其內(nèi)存。
? 另一種垃圾收集算法是“引用計(jì)數(shù)”,這種算法的思想是跟蹤記錄所有值被引用的次數(shù)。JavaScript
引擎目前都不再使用這種算法;但在 IE 中訪問(wèn)非原生 JavaScript 對(duì)象(如 DOM 元素)時(shí),這種
算法仍然可能會(huì)導(dǎo)致問(wèn)題。
? 當(dāng)代碼中存在循環(huán)引用現(xiàn)象時(shí),“引用計(jì)數(shù)”算法就會(huì)導(dǎo)致問(wèn)題。
? 解除變量的引用不僅有助于消除循環(huán)引用現(xiàn)象,而且對(duì)垃圾收集也有好處。為了確保有效地回
收內(nèi)存,應(yīng)該及時(shí)解除不再使用的全局對(duì)象、全局對(duì)象屬性以及循環(huán)引用變量的引用。
---參考《JavaScript高級(jí)程序設(shè)計(jì)第3版》
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/93781.html
摘要:另一種垃圾收集算法是引用計(jì)數(shù),這種算法的思想是跟蹤記錄所有值被引用的次數(shù)。當(dāng)代碼中存在循環(huán)引用現(xiàn)象時(shí),引用計(jì)數(shù)算法就會(huì)導(dǎo)致問(wèn)題。 垃圾回收 javascript不同于c、c++的一個(gè)特點(diǎn)是:具有自動(dòng)的垃圾回收機(jī)制,這就意味著,開發(fā)人員可以專注于業(yè)務(wù),而不必把過(guò)多精力放在內(nèi)存的管理上,提高開發(fā)效率。 所謂的垃圾回收就是找出那些不再繼續(xù)使用的變量,然后釋放其占用的內(nèi)存。為此,垃圾收集器...
摘要:內(nèi)存回收此時(shí),局部變量就沒(méi)有存在的必要了,因此可以釋放它們的內(nèi)存以供將來(lái)使用。局部變量會(huì)在它們離開執(zhí)行環(huán)境時(shí)自動(dòng)被解除引用,如下面這個(gè)例子所示手工解除的引用由于局部變量在函數(shù)執(zhí)行完畢后就離開了其執(zhí)行環(huán)境,因此無(wú)需我們顯式地去為它解除引用。 JavaScript 具有自動(dòng)垃圾收集機(jī)制(GC:Garbage Collecation),也就是說(shuō),執(zhí)行環(huán)境會(huì)負(fù)責(zé)管理代碼執(zhí)行過(guò)程中使用的內(nèi)存。而...
摘要:可以改成下面代碼手動(dòng)移除事件監(jiān)聽器和變量例四清除定時(shí)器清除變量鏈接觀察垃圾回收是怎么工作的在上面圖片中,可以觀察到,點(diǎn)擊按鈕,內(nèi)存和節(jié)點(diǎn)數(shù)暴增,當(dāng)點(diǎn)擊時(shí),垃圾收集器回收了這些定時(shí)器變量等,從而釋放了內(nèi)存。 簡(jiǎn)介 本篇文章講解JavaScript 中垃圾回收機(jī)制,內(nèi)存泄漏,結(jié)合一些常遇到的例子,相信各位看完后,會(huì)對(duì)JS 中垃圾回收機(jī)制有個(gè)深入的了解。 我的github,歡迎 star 內(nèi)...
摘要:一前言的垃圾回收機(jī)制使用垃圾回收機(jī)制來(lái)自動(dòng)管理內(nèi)存。垃圾回收器只會(huì)針對(duì)新生代內(nèi)存區(qū)老生代指針區(qū)以及老生代數(shù)據(jù)區(qū)進(jìn)行垃圾回收。分別對(duì)新生代和老生代使用不同的垃圾回收算法來(lái)提升垃圾回收的效率。 V8 實(shí)現(xiàn)了準(zhǔn)確式 GC,GC 算法采用了分代式垃圾回收機(jī)制。因此,V8 將內(nèi)存(堆)分為新生代和老生代兩部分。 一、前言 V8的垃圾回收機(jī)制:JavaScript使用垃圾回收機(jī)制來(lái)自動(dòng)管理內(nèi)存。垃...
閱讀 898·2023-04-26 01:37
閱讀 3371·2021-09-02 15:40
閱讀 961·2021-09-01 10:29
閱讀 2895·2019-08-29 17:05
閱讀 3425·2019-08-28 18:02
閱讀 1183·2019-08-28 18:00
閱讀 1492·2019-08-26 11:00
閱讀 2613·2019-08-26 10:27