1. 程式人生 > 其它 >前端面試題9----js垃圾回收機制

前端面試題9----js垃圾回收機制

技術標籤:前端面試題javascript

9.js垃圾回收機制

概述
自動垃圾回收機制就是找出那些不再繼續使用的值,然後釋放其佔用的記憶體空間。垃圾回收器每隔固定的時間段就執行一次釋放操作。
js最常用的是通過標記清除的演算法來找到哪些物件是不再繼續使用的
在區域性作用域中,當函式執行完畢的時候,區域性變數也就沒有存在的必要了,因此垃圾回收器很容易做出判斷並回收。
但是全域性變數什麼時候需要自動釋放記憶體空間則很難判斷,因此在開發中,需要儘量避免使用全域性變數。
js的記憶體管理是自動執行的,是不可見的

變數的生命週期
當一個變數的生命週期結束之後它所指向的記憶體就應該被釋放。JS有兩種變數,全域性變數和在函式中產生的區域性變數。區域性變數的生命週期在函式執行過後就結束了,此時便可將它引用的記憶體釋放(即垃圾回收),但全域性變數生命週期會持續到瀏覽器關閉頁面。

var a=20;//在記憶體中給數值變數分配空間
alert(a+100);//使用記憶體
a=null;//使用完畢後,釋放記憶體空間

檢測垃圾的方法
(1)標記清除法
不能釋放“進入環境”的變數所佔的記憶體,只要執行流進入相應的環境,就有可能用到他們。而當變數離開環境的時候,則將其標記為“離開環境”。
進行標記的方式有很多種:翻轉某個特殊位來來記錄一個變數何時進入環境;使用一個“進入環境”變數列表和一個“離開環境”列表;
垃圾回收器在執行的時候會給所有變數都加上標記,然後,環境中的變數以及環境中的變數引用的變數,他們身上的標記會被去掉。
而在此之後再被加上標記的變數將被視為準備刪除的變數,原因是環境中的變數已經無法訪問到這些變量了。

最後,垃圾收集器完成記憶體清除工作,銷燬那些帶標記的值並回收它們所佔用的記憶體空間。

function test(){ 
 var a = 10 ; //被標記 ,進入環境 
 var b = 20 ; //被標記 ,進入環境 
} 

test(); //執行完畢 之後 a、b又被標離開環境,被回收。

(2)引用計數法(跟蹤記錄每個值被引用的次數。)
當聲明瞭一個變數,並將一個引用型別值賦值給該變數時,則這個值的引用次數就是1。
如果同一個值又被賦給另外一個變數,則該值得引用次數加1。
相反,如果包含對這個值引用的變數又取得了另外一個值,則這個值的引用次數減 1。
當這個值的引用次數變成 0時,則說明沒有辦法再訪問這個值了,因而就可以將其佔用的記憶體空間回收回來。

這樣,當垃圾收集器下次再執行時,它就會釋放那 些引用次數為零的值所佔用的記憶體。

但是很重要的一點是當遇到迴圈引用的時候,函式的引用次數就不會為0,所以不會被垃圾回收器回收記憶體,會造成記憶體洩露。在IE中涉及COM物件,就會存在迴圈引用的問題。


function test(){ 
 	var a = {} ; //a的引用次數為0 
 	var b = a ; //a的引用次數加1,為1 
 	var c =a; //a的引用次數再加1,為2 
 	var b ={}; //a的引用次數減1,為1  
}