摘要:為此,垃圾收集器會按照固定的時間間隔或代碼執(zhí)行中預(yù)定的收集時間,周期性地執(zhí)行這一操作。例如,其和中的對象就是使用以,組件對象模型對象的形式實現(xiàn)的,而對象的垃圾收集機制采用的就是引用計數(shù)策略。
垃圾收集(garbage collection)
在編寫 JavaScript 程序時,開發(fā)人員不用再關(guān)心內(nèi)存使用問題,所需內(nèi)存的分配以及無用內(nèi)存的回收完全實現(xiàn)了自動管理。這種垃圾收集機制的原理其實很簡單:找出那些不再繼續(xù)使用的變量,然后釋放其占用的內(nèi)存。為此,垃圾收集器會按照固定的時間間隔(或代碼執(zhí)行中預(yù)定的收集時間),周期性地執(zhí)行這一操作。
垃圾收集器必須跟蹤哪個變量有用哪個變量沒用,對于不再有用的變量打上標(biāo)記,以備將來收回其占用的內(nèi)存。用于標(biāo)識無用變量的策略可能會因?qū)崿F(xiàn)而異,但具體到瀏覽器中的實現(xiàn),則通常有兩個策略:標(biāo)記清除和引用計數(shù)。
標(biāo)記清除(mark-and-sweep)垃圾收集器在運行的時候會給存儲在內(nèi)存中的所有變量都加上標(biāo)記(當(dāng)然,可以使用任何標(biāo)記方式)。然后,它會去掉環(huán)境中的變量以及被環(huán)境中的變量引用的變量的標(biāo)記。而在此之后再被加上標(biāo)記的變量將被視為準(zhǔn)備刪除的變量,原因是環(huán)境中的變量已經(jīng)無法訪問到這些變量了。最后,垃圾收集器完成內(nèi)存清除工作,銷毀那些帶標(biāo)記的值并回收它們所占用的內(nèi)存空間。
到 2008 年為止, IE、 Firefox、 Opera、 Chrome 和 Safari 的 JavaScript 實現(xiàn)使用的都是標(biāo)記清除式的垃圾收集策略(或類似的策略),只不過垃圾收集的時間間隔互有不同。
引用計數(shù)(reference counting)當(dāng)聲明了一個變量并將一個引用類型值賦給該變量時,則這個值的引用次數(shù)就是 1。如果同一個值又被賦給另一個變量,則該值的引用次數(shù)加 1。相反,如果包含對這個值引用的變量又取得了另外一個值,則這個值的引用次數(shù)減 1。當(dāng)這個值的引用次數(shù)變成 0 時,則說明沒有辦法再訪問這個值了,因而就可以將其占用的內(nèi)存空間回收回來。這樣,當(dāng)垃圾收集器下次再運行時,它就會釋放那些引用次數(shù)為零的值所占用的內(nèi)存。
但在采用引用計數(shù)策略的實現(xiàn)中,當(dāng)函數(shù)執(zhí)行完畢后,函數(shù)內(nèi)部循環(huán)引用的對象還將繼續(xù)存在,因為它們的引用次數(shù)永遠(yuǎn)不會是 0。假如這個函數(shù)被重復(fù)多次調(diào)用,就會導(dǎo)致大量內(nèi)存得不到回收。正是由于這個原因,Netscape在Navigator 4.0中放棄了引用計數(shù)方式,轉(zhuǎn)而采用垃圾回收。
//循環(huán)引用實例 function problem(){ var objectA = new Object(); var objectB = new Object(); objectA.someOtherObject = objectB; objectB.anotherObject = objectA; }
IE 中有一部分對象并不是原生 JavaScript 對象。例如,其 BOM 和 DOM 中的對象就是使用 C++以 COM(Component Object Model,組件對象模型)對象的形式實現(xiàn)的,而 COM 對象的垃圾收集機制采用的就是引用計數(shù)策略。因此,即使 IE 的 JavaScript 引擎是使用標(biāo)記清除策略來實現(xiàn)的,但JavaScript 訪問的 COM 對象依然是基于引用計數(shù)策略的。換句話說,只要在 IE 中涉及 COM 對象,就會存在循環(huán)引用的問題。為了避免類似這樣的循環(huán)引用問題,最好是在不使用它們的時候手工斷開原生 JavaScript 對象與DOM 元素之間的連接(賦值為null)。
IE9 把 BOM 和 DOM 對象都轉(zhuǎn)換成了真正的 JavaScript 對象。這樣,就避免了兩種垃圾收集算法并存導(dǎo)致的問題,也消除了常見的內(nèi)存泄漏現(xiàn)象。
總結(jié):內(nèi)存的自動回收基于兩種策略:其中的引用計數(shù)策略在對象循環(huán)引用時不可用,IE8及以下的DOM和BOM對象操作深受其害;目前,IE9+和其他四大瀏覽器基本支持標(biāo)記清除方式,區(qū)別僅在于垃圾回收的周期不同。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/80497.html
摘要:因此,所有在方法中定義的變量都是放在棧內(nèi)存中的當(dāng)我們在程序中創(chuàng)建一個對象時,這個對象將被保存到運行時數(shù)據(jù)區(qū)中,以便反復(fù)利用因為對象的創(chuàng)建成本通常較大,這個運行時數(shù)據(jù)區(qū)就是堆內(nèi)存。 上一篇:《javascript高級程序設(shè)計》筆記:繼承近幾篇博客都會圍繞著圖中的知識點展開 showImg(https://segmentfault.com/img/bVY0C4?w=1330&h=618);...
摘要:面試總結(jié)最近兩周面試了幾家公司高級工程師的職位,主要有宜信網(wǎng)信金融阿里高德口袋購物。目前有部分公司已經(jīng)面試通過,兩家在等消息。今天趁熱把常見面試內(nèi)容總結(jié)一下。可以用來完成統(tǒng)一命名服務(wù)狀態(tài)同步服務(wù)集群管理分布式應(yīng)用配置項等管理工作。 面試總結(jié) 最近兩周面試了幾家公司Java高級工程師的職位,主要有宜信、網(wǎng)信金融、阿里高德、口袋購物。目前有部分公司已經(jīng)面試通過,兩家在等消息。今天趁熱把常見...
摘要:執(zhí)行返回的內(nèi)部函數(shù),依然能訪問變量輸出閉包中的作用域鏈理解作用域鏈對理解閉包也很有幫助。早期的版本里采用是計數(shù)的垃圾回收機制,閉包導(dǎo)致內(nèi)存泄露的一個原因就是這個算法的一個缺陷。 關(guān)于閉包,我翻了幾遍書,看了幾遍視頻,查了一些資料,可是還是迷迷糊糊的,干脆自己動手來個總結(jié)吧 !歡迎指正... (~ o ~)~zZ 1. 什么是閉包? 來看一些關(guān)于閉包的定義: 閉包是指有權(quán)...
摘要:另一種垃圾收集算法是引用計數(shù),這種算法的思想是跟蹤記錄所有值被引用的次數(shù)。當(dāng)代碼中存在循環(huán)引用現(xiàn)象時,引用計數(shù)算法就會導(dǎo)致問題。 垃圾回收 javascript不同于c、c++的一個特點是:具有自動的垃圾回收機制,這就意味著,開發(fā)人員可以專注于業(yè)務(wù),而不必把過多精力放在內(nèi)存的管理上,提高開發(fā)效率。 所謂的垃圾回收就是找出那些不再繼續(xù)使用的變量,然后釋放其占用的內(nèi)存。為此,垃圾收集器...
閱讀 2256·2021-11-25 09:43
閱讀 3123·2021-10-14 09:42
閱讀 3484·2021-10-12 10:12
閱讀 1526·2021-09-07 10:17
閱讀 1901·2019-08-30 15:54
閱讀 3181·2019-08-30 15:54
閱讀 1550·2019-08-30 15:53
閱讀 1908·2019-08-29 11:21