溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

瀏覽器中垃圾回收機(jī)制的示例分析

發(fā)布時(shí)間:2022-03-23 11:16:51 來(lái)源:億速云 閱讀:336 作者:小新 欄目:web開(kāi)發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)瀏覽器中垃圾回收機(jī)制的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

瀏覽器的垃圾回收機(jī)制

垃圾回收是一種自動(dòng)的內(nèi)存管理機(jī)制。當(dāng)計(jì)算機(jī)上的動(dòng)態(tài)內(nèi)存不再需要時(shí),就應(yīng)該予以釋放。

需要注意的是,自動(dòng)的意思是瀏覽器可以自動(dòng)幫助我們回收內(nèi)存垃圾,但并不代表我們不用關(guān)心內(nèi)存管理,如果操作不當(dāng),JavaScript中仍然會(huì)出現(xiàn)內(nèi)存溢出的情況,造成系統(tǒng)崩潰。

由于字符串,數(shù)組,對(duì)象等都沒(méi)有固定大小,因此需要當(dāng)它們大小已知時(shí),才能對(duì)他們進(jìn)行動(dòng)態(tài)的存儲(chǔ)分配。JavaScript程序每次創(chuàng)建字符串,數(shù)組或?qū)ο髸r(shí),解釋器都必須分配內(nèi)存來(lái)存儲(chǔ)那個(gè)實(shí)體。

JavaScript解釋器可以檢測(cè)到何時(shí)程序不在使用一個(gè)對(duì)象了,當(dāng)它確定這個(gè)對(duì)象是無(wú)用的時(shí)候,他就知道不再需要這個(gè)對(duì)象了,就可以把它占用的內(nèi)存釋放掉了。

瀏覽器通常采用的垃圾回收有兩種方法:標(biāo)記清除,引用計(jì)數(shù)

標(biāo)記清除

這是JavaScript中最常用的垃圾回收方式

從2012年起,所有現(xiàn)代瀏覽器都使用了標(biāo)記清除的垃圾回收方法,除了低版本IE還是采用的引用計(jì)數(shù)法。

那么什么叫標(biāo)記清除呢?

JavaScript中有一個(gè)全局對(duì)象,定期的,垃圾回收器將從這個(gè)全局對(duì)象開(kāi)始,找出所有從這個(gè)全局對(duì)象開(kāi)始引用的對(duì)象,再找這些對(duì)象引用的對(duì)象...對(duì)這些活躍的對(duì)象標(biāo)記,這是標(biāo)記階段。清楚階段就是清楚那些沒(méi)有被標(biāo)記的對(duì)象。

標(biāo)記清除有一個(gè)問(wèn)題,就是在清除之后,內(nèi)存空間是不連續(xù)的,即出現(xiàn)了內(nèi)存碎片。如果后面需要一個(gè)比較大的連續(xù)的內(nèi)存空間,那將不能滿(mǎn)足要求。而標(biāo)記整理 方法可以有效德地解決這個(gè)問(wèn)題。

在標(biāo)記的過(guò)程中,引入了概念:三色標(biāo)記法,三色為:

  • 白:未被標(biāo)記的對(duì)象,即不可達(dá)對(duì)象(沒(méi)有掃描到的對(duì)象),可回收

  • 灰:已被標(biāo)記的對(duì)象(可達(dá)對(duì)象),但是對(duì)象還沒(méi)有被掃描完,不可回收

  • 黑:已被掃描完(可達(dá)對(duì)象),不可回收

標(biāo)記整理:

標(biāo)記階段與標(biāo)記清除法沒(méi)什么區(qū)別,只是標(biāo)記結(jié)束后,標(biāo)記整理法會(huì)將存活的對(duì)象向內(nèi)存的一邊移動(dòng),最后清理掉邊界內(nèi)存。

引用計(jì)數(shù)

引用計(jì)數(shù)的含義是跟蹤記錄每個(gè)值被引用的次數(shù)。當(dāng)一個(gè)變量A被賦值時(shí),這個(gè)值的引用次數(shù)就是1,當(dāng)變量A重新賦值后,則之前那個(gè)值的引用次數(shù)就減1。當(dāng)引用次數(shù)變成0時(shí),則說(shuō)明沒(méi)有辦法再訪(fǎng)問(wèn)這個(gè)值了,所以就可以清除這個(gè)值占用的內(nèi)存了。

大多數(shù)瀏覽器已經(jīng)放棄了這種回收方式

內(nèi)存泄漏

為避免內(nèi)存泄漏,一旦數(shù)據(jù)不再使用,最好通過(guò)將其值設(shè)為null來(lái)釋放其引用,這個(gè)方法叫做接觸引用

哪些情況會(huì)造成內(nèi)存泄漏?如何避免?

以 Vue 為例,通常有這些情況:

  • 監(jiān)聽(tīng)在 window/body 等事件沒(méi)有解綁

  • 綁在 EventBus 的事件沒(méi)有解綁

  • Vuex 的 $store,watch 了之后沒(méi)有 unwatch

  • 使用第三方庫(kù)創(chuàng)建,沒(méi)有調(diào)用正確的銷(xiāo)毀函數(shù)

解決辦法:beforeDestroy 中及時(shí)銷(xiāo)毀

  • 綁定了 DOM/BOM 對(duì)象中的事件 addEventListener ,removeEventListener

  • 觀(guān)察者模式 $on,$off處理。

  • 如果組件中使用了定時(shí)器,應(yīng)銷(xiāo)毀處理。

  • 如果在 mounted/created 鉤子中使用了第三方庫(kù)初始化,對(duì)應(yīng)的銷(xiāo)毀。

  • 使用弱引用 weakMap、weakSet

瀏覽器中不同類(lèi)型變量的內(nèi)存都是何時(shí)釋放的?

  • 引用類(lèi)型

    • 在沒(méi)有引用之后,通過(guò) V8 自動(dòng)回收。

  • 基本類(lèi)型

    • 如果處于閉包的情況下,要等閉包沒(méi)有引用才會(huì)被 V8 回收。

    • 非閉包的情況下,等待 V8 的新生代切換的時(shí)候回收。

關(guān)于“瀏覽器中垃圾回收機(jī)制的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI