Js具有自動垃圾回收機(jī)制丝里。垃圾收集器會按照固定的時(shí)間間隔周期性的執(zhí)行。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
JS中最常見的垃圾回收方式是標(biāo)記清除。
工作原理:是當(dāng)變量進(jìn)入環(huán)境時(shí),將這個(gè)變量標(biāo)記為“進(jìn)入環(huán)境”。當(dāng)變量離開環(huán)境時(shí)刘离,則將其標(biāo)記為“離開環(huán)境”室叉。標(biāo)記“離開環(huán)境”的就回收內(nèi)存。
工作流程:
1.????垃圾回收器硫惕,在運(yùn)行的時(shí)候會給存儲在內(nèi)存中的所有變量都加上標(biāo)記太惠。
2.????去掉環(huán)境中的變量以及被環(huán)境中的變量引用的變量的標(biāo)記。
3.????再被加上標(biāo)記的會被視為準(zhǔn)備刪除的變量疲憋。
4.????垃圾回收器完成內(nèi)存清除工作,銷毀那些帶標(biāo)記的值并回收他們所占用的內(nèi)存空間梁只。
引用計(jì)數(shù)?方式
工作原理:跟蹤記錄每個(gè)值被引用的次數(shù)缚柳。
工作流程:
1.????聲明了一個(gè)變量并將一個(gè)引用類型的值賦值給這個(gè)變量,這個(gè)引用類型值的引用次數(shù)就是1搪锣。
2.????同一個(gè)值又被賦值給另一個(gè)變量秋忙,這個(gè)引用類型值的引用次數(shù)加1.
3.????當(dāng)包含這個(gè)引用類型值的變量又被賦值成另一個(gè)值了,那么這個(gè)引用類型值的引用次數(shù)減1.
4.????當(dāng)引用次數(shù)變成0時(shí)构舟,說明沒辦法訪問這個(gè)值了灰追。
5.????當(dāng)垃圾收集器下一次運(yùn)行時(shí),它就會釋放引用次數(shù)是0的值所占的內(nèi)存狗超。
但是循環(huán)引用的時(shí)候就會釋放不掉內(nèi)存弹澎。循環(huán)引用就是對象A中包含另一個(gè)指向?qū)ο驜的指針,B中也包含一個(gè)指向A的引用努咐。
因?yàn)镮E中的BOM苦蒿、DOM的實(shí)現(xiàn)使用了COM,而COM對象使用的垃圾收集機(jī)制是引用計(jì)數(shù)策略渗稍。所以會存在循環(huán)引用的問題佩迟。
解決:手工斷開js對象和DOM之間的鏈接。賦值為null竿屹。IE9把DOM和BOM轉(zhuǎn)換成真正的JS對象了报强,所以避免了這個(gè)問題。
什么情況會引起內(nèi)存泄漏拱燃?
雖然有垃圾回收機(jī)制但是我們編寫代碼操作不當(dāng)還是會造成內(nèi)存泄漏秉溉。
1.????意外的全局變量引起的內(nèi)存泄漏。
原因:全局變量扼雏,不會被回收坚嗜。
解決:使用嚴(yán)格模式避免。
2.????閉包引起的內(nèi)存泄漏
原因:閉包可以維持函數(shù)內(nèi)局部變量诗充,使其得不到釋放苍蔬。
解決:將事件處理函數(shù)定義在外部,解除閉包,或者在定義事件處理函數(shù)的外部函數(shù)中蝴蜓,刪除對dom的引用碟绑。
3.????沒有清理的DOM元素引用
原因:雖然別的地方刪除了俺猿,但是對象中還存在對dom的引用
解決:手動刪除。
4.????被遺忘的定時(shí)器或者回調(diào)
原因:定時(shí)器中有dom的引用格仲,即使dom刪除了押袍,但是定時(shí)器還在,所以內(nèi)存中還是有這個(gè)dom凯肋。
解決:手動刪除定時(shí)器和dom谊惭。
5.????子元素存在引用引起的內(nèi)存泄漏
原因:div中的ul li? 得到這個(gè)div,會間接引用某個(gè)得到的li侮东,那么此時(shí)因?yàn)閐iv間接引用li圈盔,即使li被清空,也還是在內(nèi)存中悄雅,并且只要li不被刪除驱敲,他的父元素都不會被刪除。
解決:手動刪除清空宽闲。
什么放在內(nèi)存中众眨?什么不放在內(nèi)存中?
基本類型是:Undefined/Null/Boolean/Number/String
基本類型的值存在內(nèi)存中容诬,被保存在棧內(nèi)存中娩梨。從一個(gè)變量向另一個(gè)變量復(fù)制基本類型的值,會創(chuàng)建這個(gè)值的一個(gè)副本放案。
引用類型:object
引用類型的值是對象姚建,保存在堆內(nèi)存中。
1.????包含引用類型值的變量實(shí)際上包含的并不是對象本身吱殉,而是一個(gè)指向該對象的指針掸冤。從一個(gè)變量向另一個(gè)變量復(fù)制引用類型的值,復(fù)制的其實(shí)是指針友雳,因此兩個(gè)變量最終都指向同一個(gè)對象稿湿。
2.????js不允許直接訪問內(nèi)存中的位置,也就是不能直接訪問操作對象的內(nèi)存空間押赊。在操作對象時(shí)饺藤,實(shí)際上是在操作對象的引用而不是實(shí)際的對象。
棧和堆的區(qū)別
一流礁、堆椞樗祝空間分配區(qū)別:
1、棧(操作系統(tǒng)):由操作系統(tǒng)自動分配釋放 神帅,存放函數(shù)的參數(shù)值再姑,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧找御;
2元镀、堆(操作系統(tǒng)): 一般由程序員分配釋放绍填,若程序員不釋放,程序結(jié)束時(shí)可能由OS回收栖疑,分配方式倒是類似于鏈表讨永。
二、堆棧緩存方式區(qū)別:
1遇革、棧使用的是一級緩存卿闹, 他們通常都是被調(diào)用時(shí)處于存儲空間中,調(diào)用完畢立即釋放萝快;
2比原、堆是存放在二級緩存中,生命周期由虛擬機(jī)的垃圾回收算法來決定(并不是一旦成為孤兒對象就能被回收)杠巡。所以調(diào)用這些對象的速度要相對來得低一些。
三雇寇、堆棧數(shù)據(jù)結(jié)構(gòu)區(qū)別:
堆(數(shù)據(jù)結(jié)構(gòu)):堆可以被看成是一棵樹氢拥,如:堆排序;
棧(數(shù)據(jù)結(jié)構(gòu)):一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu)锨侯。
歡迎工作一到五年的Java工程師朋友們加入Java架構(gòu)開發(fā):855801563
本群提供免費(fèi)的學(xué)習(xí)指導(dǎo)?架構(gòu)資料?以及免費(fèi)的解答
不懂得問題都可以在本群提出來?之后還會有職業(yè)生涯規(guī)劃以及面試指導(dǎo)
同時(shí)大家可以多多關(guān)注一下小編 純干貨?大家一起學(xué)習(xí)進(jìn)步