引出我們的主角
我們先來回憶一下,全局變量,系統(tǒng)會在頁面關(guān)閉時進行釋放占用的內(nèi)存,函數(shù)局部變量,會在函數(shù)執(zhí)行完畢時進行釋放內(nèi)存,這就是今天我們的主角:Js的垃圾回收機制。
所有的語言,都需要處理這個過程,比如C語言,需要開發(fā)者進行手動,申請與釋放內(nèi)存
而 Javascript 自動幫我們做了內(nèi)存管理,完成了整個內(nèi)存管理生命周期,讓開發(fā)者專注于業(yè)務(wù)邏輯本身
但同時也給開發(fā)者造成了——可以不關(guān)心內(nèi)存管理的假象。
總結(jié)一下這個過程:
· 分配你所需要的內(nèi)存
· 使用分配到的內(nèi)存(讀、寫)
· 不需要時將其釋放\歸還
下面說一下垃圾回收兩個重要的點:
· 內(nèi)存泄漏
當一些不再被需要的內(nèi)存,由于某種原因,無法被釋放。就會造成內(nèi)存泄漏,導(dǎo)致程序內(nèi)存被占用,直至崩潰。
· 可達性
垃圾回收的標準就是對象是否可達,變量是否能被引用
引用
對象{ name: xxx }的內(nèi)存地址,被a,b兩個變量引用兩次,當a被賦值為null,因為b還在引用,可達,所以沒有被回收
當test1()被執(zhí)行,系統(tǒng)為obj分配內(nèi)存,當函數(shù)執(zhí)行完畢,內(nèi)存被回收。
當test2()被執(zhí)行obj也開辟了內(nèi)存,但obj被返回結(jié)果 賦值給了b,成為了全局變量,不會被銷毀
介紹一下垃圾回收實現(xiàn)的兩種常用的方法:
1、引用清除(IE9之前采用)
變量聲明以后被引用的次數(shù),為 0 時,該變量內(nèi)存被銷毀
優(yōu)點
· 即刻回收垃圾,當被引用數(shù)值為0時,就會立刻被回收
· 不用去遍歷堆里面的所有活動對象和非活動對象
缺點
· 計數(shù)器需要占很大的位置,因為不能預(yù)估被引用的上限
· 最大的劣勢是無法解決循環(huán)引用無法回收的問題
上面a,b互相引用,計數(shù)不會等于0,內(nèi)存不會回收,重復(fù)調(diào)用,會占用大量內(nèi)存
2、V8引擎里面 (現(xiàn)在基本采用,標記清除)
是瀏覽器中Javascript解析引擎V8采用,標記階段:把所有活動對象做上標記,把沒有標記(也就是非活動對象)銷毀,
從全局作用域的變量,沿作用域逐層往里深度遍歷,當發(fā)現(xiàn)被引用,打上標記,執(zhí)行完畢,將沒有被標記的變量內(nèi)存,進行銷毀
說一說常見的內(nèi)存泄漏
Foo 被調(diào)用時, this 指向全局變量(window),相當于與是全局變量,變量不會被回收
當節(jié)點被干掉,定時器還是會不停執(zhí)行
閉包
計數(shù)器
既實現(xiàn)遞增,又不污染全局環(huán)境, 子函數(shù)引用父函數(shù)變量num,父函數(shù)執(zhí)行完畢num不會被回收, 當子函數(shù)執(zhí)行完畢返回賦值最外層全局環(huán)境變量add,記錄狀態(tài), 這其實也是內(nèi)存泄露案例
關(guān)閉內(nèi)存管理
· 一般棧存放(基本類型的值)不會泄漏,堆存放(引用類型的值是對象)才會造成泄漏
· 一般小內(nèi)存泄露不會對程序造成影響,但是大型項目,防止積少成多,養(yǎng)成良好編程習慣
更多關(guān)于html5培訓(xùn)的問題,歡迎咨詢千鋒教育在線名師,如果想要了解我們的師資、課程、項目實操的話可以點擊咨詢課程顧問,獲取試聽資格來試聽我們的課程,在線零距離接觸千鋒教育大咖名師,讓你輕松從入門到精通。