您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)瀏覽器中垃圾回收機(jī)制的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
垃圾回收是一種自動(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)把它分享出去讓更多的人看到。
免責(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)容。