実行時メモリ構造



これからの物事を理解するために、プログラムが動いている時のメモリ領域の構造を図 に示す。

大まかには、Java, ML, C 言語も含めほとんどの言語は似たような構造になる。

ヒープ内の小さい四角はオブジェクトを表す。

また、あるオブジェクトA の中に含まれるポインタが、別のオブジェクトB を指していることがある。

(record の中にrecord がある場合や、オブジェクトのフィールドに別のオブジェクトを含む場合など)

図中では参照関係を、A からB への矢印で表す。

スタックには、局所変数や関数呼び出しの履歴などが格納される。(話をごく簡単にすると) 関数呼び出しが起こると伸びて、return が起こると縮む。 大域変数を格納する領域が用意される。定数が格納される領域も独立に用意される場合が多い。 レジスタは、関数の引数、計算の途中結果など様々な値をとる。オブジェクトを指すポインタの可能性もある。 ヒープは自由な順番でメモリ領域を確保/解放できる領域である。 オブジェクト作成(C ではmalloc)を行なうと、ヒープの中に必要な大きさの領域が確保される。

図には示していないが、プログラムのコード領域もどこかにある。 これからの物事を理解するために、プログラムが動いている時のメモリ領域の構造を図 に示す。大まかには、Java, ML, C 言語も含めほとんどの言語は似たような構造になる。ヒープ内の小さい四角はオブジェクトを表す。また、あるオブジェクトA の中に含まれるポインタが、別のオブジェクトB を指していることがある。(record の中にrecord がある場合や、オブジェクトのフィールドに別のオブジェクトを含む場合など)図中では参照関係を、A からB への矢印で表す。オブジェクト作成(C ではmalloc)を行なうと、ヒープの中に必要な大きさの領域が確保される。

基本アルゴリズム編 世の中にあるGCアルゴリズムはこの3パターンに最終的に集約される．

基本中の基本のアルゴリズムである．



応用アルゴリズム編 ここでは基本アルゴリズムを応用し、欠点を解決したアルゴリズムの紹介をする。



補足

conservativeGC(保守的GC)

そのオブジェクトの解放は行わない。

つまり、数値であった場合にポインタの値を変更(CopyGCなど)した時はプログラムとして致命的である為、

何も触らない方向に倒すという事だ。

まさに保守的なGCだ。



利点 無駄な細工をせずに済むので処理が軽い

実装が楽

欠点 回収されないゴミが残る可能性がある

CopyingGCなどオブジェクトを移動する事ができない。 →解決方法1：オブジェクトとポインタの間に一枚ハンドルを噛まして抽象化する。

実際にハンドルの数値だけが変わり元のポインタに影響はない。

(間接参照になる為、通常の処理が遅くなる欠点)



詳細な解説 ConservativeGCとは何か conservativeGCはこの場合、オブジェクトへの参照では無く、只の数値だったとしてもそのオブジェクトの解放は行わない。つまり、数値であった場合にポインタの値を変更(CopyGCなど)した時はプログラムとして致命的である為、何も触らない方向に倒すという事だ。まさに保守的なGCだ。→解決方法1：オブジェクトとポインタの間に一枚ハンドルを噛まして抽象化する。実際にハンドルの数値だけが変わり元のポインタに影響はない。(間接参照になる為、通常の処理が遅くなる欠点)

exactGC(絶対的GC)

exactGCではポインタと数値をはっきり区別し、ゴミを残さず回収する事をポリシーとする。

ポインタと数値を区別する具体的な方法は、 整数値の範囲を1 bit減らして、その1bitをタグビットとして利用する。

stack map方式 がある。



ほとんどの処理系は，処理系自身がルートを提供する事であいまいなポインタがなくなりexactGCとなる．

この場合，GCにより協力的な処理系と言える．



利点 ゴミを全て回収するのでメモリ効率がいい

オブジェクトの移動が楽にできる。(コンパクション)

欠点 色々と制限がつく

実装が面倒

ちなみに「絶対的GC」という訳はオリジナル。べたに訳すと「確実なGC」になる。

またexactと同じ意味でprecise（プリサイス）と呼ぶ事もある．

（英語ではこっちの方が多いかも）

conservativeGCではなんでもオブジェクトとみなして、ゴミが残る可能性があったがexactGCではポインタと数値をはっきり区別し、ゴミを残さず回収する事をポリシーとする。ポインタと数値を区別する具体的な方法は、がある。ほとんどの処理系は，処理系自身がルートを提供する事であいまいなポインタがなくなりexactGCとなる．この場合，GCにより協力的な処理系と言える．ちなみに「絶対的GC」という訳はオリジナル。べたに訳すと「確実なGC」になる。またexactと同じ意味でprecise（プリサイス）と呼ぶ事もある．（英語ではこっちの方が多いかも）

writebarrier

これとは別に「書き換えられたオブジェクト」をチェックするために別種類の印をつける。

例えば、以下のような Java プログラムを実行しているスレッドが、 object1 のフィールドになんらかのオブジェクトの参照を書き込む場合、

object1 に「書き込まれた」という印を付けるのである。

この処理を ライトバリア (write barrier) と呼ぶ。

object2 が null でない場合は、どんなオブジェクトでもチェックを行う。 void method( Class1 object, Class2 object2 ){ object1.field = object2; } ライトバリアされた後の、メモリ中のイメージとしては下の図のようになる。







Mark&Sweepアルゴリズムでは「Root から到達可能かどうか」をチェックするためにオブジェクトにマークを行っていたが、これとは別に「書き換えられたオブジェクト」をチェックするために別種類の印をつける。例えば、以下のような Java プログラムを実行しているスレッドが、 object1 のフィールドになんらかのオブジェクトの参照を書き込む場合、object1 に「書き込まれた」という印を付けるのである。この処理を ライトバリア (write barrier) と呼ぶ。object2 が null でない場合は、どんなオブジェクトでもチェックを行う。ライトバリアされた後の、メモリ中のイメージとしては下の図のようになる。

finalize



用語集 個人的にわからなかった単語たち

tenured 和訳：保有権のある、終身在職権のある、身分保障のある

世代別GCの古い世代を置く領域の事

ミュテータ オブジェクトの状態を書き換える者、すなわちユーザープログラムのこと

scavenge 和訳：清掃をする

sweep 和訳：ゴミを掃き出す

root 和訳：根、根源

GCにおいて、「確実に必要なオブジェクト」。

スタック領域、レジスタ、グローバル変数、定数などから参照されているヒープ領域を指す。

このオブジェクトを起点に必要なオブジェクトが探索され、探索されなかったオブジェクトがGCの対象になる。

chunk 和訳：大きな塊

GCの対象になる塊、場合によってはオブジェクトだったりデータだったり

compaction Mark&Sweepを何度も繰り返すとメモリの断片化が起こるが、

その状態を整頓するする事を指す。

Windowsで言う所のデフラグの様なもの。

allocate 和訳：割り当てる

メモリ割り当てる行為。GC関連の資料では管理対象のオブジェクトを作成する事を指すことが多い。

promote 和訳：昇進させる、昇格させる

新世代から旧世代に移動させること、殿堂入りとも言う。

starvation 和訳：飢餓状態

要求に応じられるだけのフリーなデータがなくなった状態

ルート挿入 ルート集合から直接さされているセル(データ)に一括して印をつけ、GC用スタックに挿入すること