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