Incremental,Generational, Mostly-Copying Garbage Collection in Uncooperative Environments by G.May Yip, A Master Thesis, MIT, 1991 について。 発表者: 小林 義徳 http://www.research.compaq.com/wrl/techreports/abstracts/91.8.html About this GC… Incremental, generational mostly-copying garbage collector for C++ Uniprocessor 特別な hardware サポートなしで動作。 コンパイラへの変更も不要 UNIXの mprotect システムコールを使用 The collector achieves… GC 一回あたりの停止時間が短い (from incremental collection) トータルのGC 時間もそれほど長くない (from generational collection) ハードウェアやコンパイラのサポートなしで 動作 (from mostly-copying collection) 内容 Generational GC Program Interface in C++ Bartlett’s Generational MostlyCopying Collector Incremental,Generational Mostly-Copying Collection 詳細 実験結果 今後の課題 Generational GC 経験則: ほとんどのオブジェクトは生成後すぐにゴミになり、 ある程度の期間以上生き残ったオブジェクトはさらに長期に わたって生き残る 一定回数以上の GC で生き残ったオブジェクトを古いオブジェ クトとみなす。 GC の際、古いオブジェクトは、最初から生きているとして扱う。 結果として、GC の仕事を減らすことができる Generational GC(図) Old space Remembered set New space stack,registers,static area Generational GC Root set は、スタック、レジスタ、スタティック領域の変数の ほかに、 remembered set も用いる remembered set = 新しいオブジェクトを指す古いオブジェクト全体を含む集合 (Bartlett’s GC や this GC では, the remembered set = 古いオブジェクト全体) Program Interface in C++ struct word{ word *lesser,*greater; ・・・ GCCLASS(word); クラス word はGC によって回収される } word::word(char* chars){ GCALLOCV(word,sizeof(word) + strlen(chars)); ・・・ 可変サイズのクラスはGCALLOCV で allocate } void word::GCPointers(){ オブジェクト内のポインタを扱うため のgcpointer(lesser); CALLBACK gcpointer(greater); } Rules class C:P{} について、 C::GCPointers() 内に P::GCPointers()を書く class C { X x;} について、 C::GCPointers() 内に x.GCPointers() を書く class C { X* x;} について、 C::GCPointers() 内に gcpointer(x) を書く GCCLASS(word) および gcpointer(x) マクロ GCCLASS(word) インライン関数 gcpointer(x) コールバック word::GCPointers() を宣言している。 new 演算子をオーバーロードし、その中でコールバック word::GCPointers のGC への登録を行っている。 x = gcmove(x) のように展開される。 GC 時には、word::GCPointers() が呼び出され、 word 内のポインタが指すオブジェクトをコピー。 Bartlett’s Mostly-Copying Collector[1][2] Compacting,conservative collector スタックやレジスタ内の word については、 すべてポインタとして扱う。 ヒープ内に確保されるオブジェクトの構造に ついては、知っているものとする。 コンパイラのサポートが不要 Allocation 2-level allocation small objects (1ページよりも小さいオブジェクト) 1. heap page を一つ確保 2. heap page よりオブジェクトを確保 large objects (一ページよりも大きいオブジェクト) 1. 十分な量のページを確保 ページの最後の余った部分は使われない Spaces heap page (512 bytes/page) について space identifier : an integer current-space , next-space (later) type identifier : OBJECT or CONTINUED 小さいオブジェクトをもっているページ : OBJECT 大きいオブジェクト(1ページ以上) 最初のページ : OBJECT 残りのページ : CONTINUED Two Spaces current-space 新しいオブジェクトは current-space より確保 Copy GC の from-space に対応 next-space Root pointer に指されたオブジェクトをもつページ GC により動かされたオブジェクトをもつページ Copy GC の to-space に対応 Space ID を管理する変数 curr_space : current-space の space ID next_space : next-space の space ID 初期設定 curr_space = next_space = 3; GC が走っていないとき curr_space == next_space GC の最中 curr_space != next_space Heap Spaces (Normally) ID = 3 ID = 3 ID = 3 ID = 3 ID = 3 ID = 3 ID = 3 ID = 3 curr_space = next_space = 3 Allocation GC が走っていない間 オブジェクトは current-space より確保 (curr_space = next_space) GC の最中 オブジェクトをコピーするためのスペースは next-space より確保 Collection(1) allocatedpages >= heappages /2 となった時点でGC が起動される。 1. next_space = curr_space + 1; Root set を探索 (スタック、レジスタ、static 領域の変数、 remembered set) ‘root pointers’ に「指されている」 currentspace を promote (promote : spaceID = next_space) 2. 3. Collection(2) 4. 5. 古いオブジェクトおよび promote された ページより、オブジェクトを探索・コピー (幅優先探索) curr_space = curr_space + 2; next_space = curr_space; Heap Spaces (Before GC) Root set ID = 3 ID = 3 ID = 3 ID = 3 curr_space = next_space = 3 Heap Spaces (Start GC) Root set ID = 4 ID = 4 ID = 3 ID = 3 curr_space = 3 , next_space = 4 (next_space++) Heap Spaces (During GC(1)) Root set ID = 4 ID = 4 ID = 3 ID = 3 curr_space = 3 , next_space = 4 Forwarding pointer Heap Spaces (During GC(2)) Root set ID = 4 ID = 4 ID = 3 ID = 3 curr_space = 3 , next_space = 4 Forwarding pointer Heap Spaces (During GC(3)) Root set ID = 4 ID = 4 ID = 3 ID = 3 curr_space = 3 , next_space = 4 Forwarding pointer Heap Spaces (After GC) Root set ID = 4 ID = 4 ID = 5 ID = 5 curr_space = next_space = 5 (curr_space +=2,next_space++) Picking Up Generations[2] 一度でも GC を生き残ったオブジェクトを古いオブ ジェクトとみなす。 GC後、古いオブジェクトを持つページは、偶数の space identifier をもつ。 GC は、古いオブジェクト全体を remembered set として扱う。 たまには、古いオブジェクトも回収(major collection) minor collection 後、古いオブジェクトがヒープの 85 % を超えてい たとき、Mark-Compact GC を実行[3] Incremental,Generational Mostly-Copying Collector Incremental Collector アプリケーションの動作の合間に細切れにGarbage Collection を行う。GC をすこし行ったら、アプリケーションに 制御を返してしまう。 一度のGC の停止時間は短いが、totalのGC時間は長くなる ページ保護を用い、Page Faultの際に少しずつ探索と Copy を行う。(mprotect を用いて、read/write protect) Generational Collector 通常は、新しいオブジェクトのみを対象に GC を行う。 Total のGC 時間を減らすことができる。 3-space strategy current-space (変数 curr_space) 新しいオブジェクトは、current-space より確保 previous-space (prev_space) GC の最中で、未探索のページ forward-space (forw_space) Root pointer に指されているページ オブジェクトのコピー用のメモリは forward-space より確保 Bartlett’s GC の next-space に相当 GC が走っていない間は、これら3つの space の区別はない。 cf.2-spaces in Bartlett’s GC current-space 新しいオブジェクトは current-space より確保 Copy GC の from-space に対応 next-space Root pointer に指されたオブジェクトをもつページ GC により動かされたオブジェクトをもつページ Copy GC の to-space に対応 GC を開始するタイミング GC を開始するタイミング allocatedpages >= heappages /3 GC を再開するタイミング 保護されたページへのアクセスがあったとき アプリケーションが新しい heap page を確保したとき。 保護されたページをランダムに選び、GC を行う。 Start GC 1. space-ID を管理する変数を更新 (forw_space,prev_space,curr_space) 2. 3. Root set を探索 root pointer に指されているpages を promote (Promote : space-ID = forw_space) 4. 古いオブジェクトをもつページと 3. のページを保護 (mprotect 5. : read/write protect) アプリケーションに制御を返す Start GC curr_space protected pages unprotected pages A Root set forw_space = curr_space B = prev_space C prev_space = curr_space D curr_space forw_space = curr_space + 1; curr_space = curr_space + 2; Protect Pages(1) forw_space protected pages unprotected pages A Root set B C D prev_space Trap Handler’s Works (During GC) 1. 2. 3. 4. Page Fault の起こったページの保護を外す ページ内のオブジェクトを探索・コピー 2.でコピーされたオブジェクトを含むページを保護 (Protect : neither readable nor writable) アプリケーションに制御を返す。 アプリケーションが新しい heap page を確保する際、 保護されたページをランダムに選び、scan を行う。 Handle Page Fault(1) forw_space B’ C’ A forw_space B C protected pages unprotected pages forwarding pointers D prev_space Handler Protects Pages(2) forw_space B’ C’ A forw_space B C protected pages unprotected pages forwarding pointers D prev_space Handle Page Fault(2) forw_space B’ C’ A forw_space B C D’ D prev_space forw_space Handler Protects Pages(3) forw_space B’ C’ A forw_space B C D’ D prev_space forw_space Handle Page Fault(3) forw_space B’ C’ A forw_space All protected pages have been unprotected and scanned D’ forw_space Finish GC 保護されたページがなくなった時点で、GC 終了 Space-ID 変数を更新 prev_space = forw_space = curr_space (At the start of GC, prev_space = curr_space forw_space = curr_space + 1; curr_space = curr_space + 2;) 最後まで prev_space だったページはGC 後、 再利用可能になる。 Benchmark Program words テキストファイルを読み、その中の単語について、 辞書順のbinary tree を生成するプログラム。 bipsctrl WRL で作られた CAD system の一部 実験結果 Non-Incremental Generational V.S. Incremental Generational 別紙の実験結果によると、 Incremental 化による GC 処理時間の増加は、 words で 24 %, bipsctrl で にとどまっている。 7% Real-Time Performance 使用したベンチマークプログラムについて、 平均の GC の停止時間は、約 4msec ほど であった。 最大の停止時間も、せいぜい 100 msec 以 内に収まった まとめ Bartlett のGenerational Mostly-Copying GC が Incremental化された。 previous-space の概念を追加 mprotect によるページ保護 Performance もそれなりによかった 最大の停止時間も 100msec 以下に抑えられた。 Total のGC 時間もそれほど大きくならなかった。 Future Works Non-concurrent collector concurrent collector GC の初期化プロセスも incremental 化 GC 初期化処理による停止時間が一番長い GC 初期化時間は、root set の大きさに比例。 References [1] Joel F.Bartlett,1988 Compacting Garbage Collection with Ambiguous Roots [2] Joel F.Bartlett,1989 Mostly-Copying Garbage Collection Picks Up Generations and C++ [3] Richard Jones and Rafael Lins,1996 Garbage Collection,Algorithm for Automatic Dynamic Memory Management References [4] 遠藤 敏夫,1999 一般教養としての Garbage Collection
© Copyright 2024 ExpyDoc