Javascript垃圾回收淺析


    接上篇《JS特性性能缺陷及JIT的解決方案》,這里總結下的Javascript垃圾回收機制。

 

一. 枚舉Javascript引擎分配內存的場景:

1. Object

new Object();
new MyConstructor();
{ a: 4, b: 5 }
Object.create();

2. 數組

new Array();
[ 1, 2, 3, 4 ];

3. 字符串

new String(“hello hyddd”);
“<p>” + e.innerHTML + “</p>”

    隨帶一說,javascript的字符串和.Net一樣,使用資源池和copy on write方式管理字符串。

4. 函數對象

var x = function () { ... }
new Function(code);

5. 閉包

function outer(name) {
var x = name;
return function inner() {
  return “Hi, “ + name;
}
}

    閉包和prototype不一樣,以上函數為例,當調用outer時,會生成並返回一個對象(隱含變量x),每次調用都創建一個,而prototype則是每次都返回同一個而對象(即:無論多少次調用,只創建一個對象)。

 

二. GC方案

    相對其他語言的復雜的GC方案,Javascript的GC相對還是比較簡單的。

 

1. Javascript引擎基礎GC方案是(simple GC):mark and sweep(標記清除),即:

(1)遍歷所有可訪問的對象。

(2)回收已不可訪問的對象。

 

2. GC的缺陷

    和其他語言一樣,javascript的GC策略也無法避免一個問題:GC時,停止響應其他操作,這是為了安全考慮。而Javascript的GC在100ms甚至以上,對一般的應用還好,但對於JS游戲,動畫對連貫性要求比較高的應用,就麻煩了。這就是新引擎需要優化的點:避免GC造成的長時間停止響應。

 

3. GC優化策略

    David大叔主要介紹了2個優化方案,而這也是最主要的2個優化方案了:

(1)分代回收(Generation GC)

    這個和Java回收策略思想是一致的。目的是通過區分“臨時”與“持久”對象;多回收“臨時對象”區(young generation),少回收“持久對象”區(tenured generation),減少每次需遍歷的對象,從而減少每次GC的耗時。如圖:

    1

    這里需要補充的是:對於tenured generation對象,有額外的開銷:把它從young generation遷移到tenured generation,另外,如果被引用了,那引用的指向也需要修改。

 

(2)增量GC

    這個方案的思想很簡單,就是“每次處理一點,下次再處理一點,如此類推”。如圖:

    2

    這種方案,雖然耗時短,但中斷較多,帶來了上下文切換頻繁的問題。

 

4. 總結

    因為每種方案都其適用場景和缺點,因此在實際應用中,會根據實際情況選擇方案。

    比如:低 (對象/s) 比率時,中斷執行GC的頻率,simple GC更低些;如果大量對象都是長期“存活”,則分代處理優勢也不大。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM