JavaScript的自動垃圾收集機制 執行環境會負責管理代碼執行過程中使用的記憶體,編寫JavaScript程式時,所需記憶體的分配以及無用記憶體的回收完全實現自動管理。 原理: 找出那些不再繼續使用的變數,然後釋放其占用的記憶體。為此,垃圾收集器會按照固定的時間間隔(或代碼執行中預定的收集時間)周期性地 ...
JavaScript的自動垃圾收集機制
執行環境會負責管理代碼執行過程中使用的記憶體,編寫JavaScript程式時,所需記憶體的分配以及無用記憶體的回收完全實現自動管理。
原理:
找出那些不再繼續使用的變數,然後釋放其占用的記憶體。為此,垃圾收集器會按照固定的時間間隔(或代碼執行中預定的收集時間)周期性地執行這一操作。
垃圾收集的方式:
1.標記清除(mark-and-sweep)
最常用的垃圾收集方式。當變數進入環境時,就將變數標記為“進入環境”。從邏輯上講,永遠不能釋放進入環境的變數所占用的記憶體,因為只要執行流進入相應的環境,就可能會用到它們。當變數離開環境時,則將其標記為“離開環境”。
立即收集器在運行時會給存儲在記憶體中的所有變數都加上標記,然後它會去掉環境中的變數以及被環境中的變數引用的變數的標記。剩下的在被加上標記的變數將被視為準備刪除的變數,原因是環境中的變數已經無法訪問到這些變數。最後,垃圾收集器完成記憶體清除,銷毀那些帶有標記的值並收回它們所占用的記憶體空間。
2.引用計數(reference counting)
跟蹤記錄每個值被引用的次數,當這個值的引用次數為0時,說明沒有辦法再訪問這個值了,因而就可以將其占用的記憶體空間回收回來。當垃圾收集器下次再運行時,會釋放那些引用次數為零的值所占用的記憶體。
(1)應用機制存在一個問題:迴圈引用。
迴圈引用是指對象A中包含一個指向對象B的指針,而對象B中也包含一個指向對象A的引用。(這樣它們的引用可能永遠不為0,如果函數被重覆多次調用,就會導致大量的記憶體得不到回收。)
(2)IE中的BOM和DOM中的對象使用C++以COM(component Object Model,組件對象模型)對象的形式實現,而COM對象的垃圾收集機制採用的是引用計數策略。
以下是COM對象導致的迴圈引用的問題:
eg:
1 var element=document.getElementById("some_element"); 2 var myObject=new Object(); 3 myObject.element=element; 4 element.someObject=myObject;
上面的例子在一個DOM元素(element)和一個原生JavaScript對象(myObject)之間創建了迴圈引用。由於存在這個迴圈引用,即使將例子中的DOM從頁面移除,它也永遠不會被回收。
可以使用以下代碼手工斷開原生JavaScript和DOM元素之間的鏈接:
1 myObject.element=null; 2 element.someObject=null;