自動メモリ管理
newobj命令
- バイト数計算(型・フィールド)
- バイト数にオーバーヘッド領域(型オブジェクトポインタ・同期ブロックインデックス)を加で必要となる分を加算
- 8バイト(64ビットアプリケーションなら16バイト)
- 予約領域を確認
- 確保できるならNextObjPtrが指すアドレスに確保
- バイトをゼロクリア
- コンストラクタ呼出
- NextObjPtrを進める
- オブジェクトのアドレスを返す
ガベージコレクション
ルート
参照型オブジェクトのメモリポインタの位置。
OutOfMemoryException
ガベージコレクションの後でヒープに空きメモリが存在しない場合、new演算子を実行するとthrowされる。
ガベージコレクション
- すべてをゴミと仮定
- マーキング
- スレッドスタックをさかのぼり、ルートをチェック
- ルート見つける→同期ブロックインデックスのビットをオン(これが「マーク」)
- 到達可能なすべてのオブジェクトを再帰的に辿り続ける
- すでにマークされたオブジェクトを発見すると、それ以上の探索は中止する
- パフォーマンス向上と、循環参照による無限ループ対策のため
- すでにマークされたオブジェクトを発見すると、それ以上の探索は中止する
- コンパクト化
- 大きな連続したブロックを見つけてオブジェクトを移動させる
- 移動したオブジェクトを参照しているフィールドを修正
- NextObjPtrをゴミではない最後のオブジェクトの直後の場所へ移動
ガベージコレクションの契機
ファイナライゼーション
- Finalize
- クリーンな後処理のためのメカニズム
- 呼び出すタイミングはガベージコレクタ任せ
- ガベージコレクト完了時に呼び出される
ファイナライゼーションリスト
- インスタンスコンストラクタ呼出直前にオブジェクトのポインタを登録
- ガベージコレクション発生時、ポインタが探索され、見つかったら削除→Fリーチャブルキューに追加
Fリーチャブルキュー
- Finalize用の優先度の高いスレッドがFinalize呼出を担当。
- Fリーチャブルキューにエントリが入るとスレッドが活性化
- キューからエントリを削除し、オブジェクトのFinalizeメソッドを呼び出す
- Fリーチャブルキューが参照している限り、オブジェクトはガベージコレクションの対象にはならない(=Finalize呼出が完了して初めて、オブジェクトはガベージコレクションの対象となり、削除される)
ジェネレーション
CLRガベージコレクタがアプリケーションパフォーマンス向上に使用するメカニズムを「ジェネレーション」という。(いわゆる世代別GC)
→http://d.hatena.ne.jp/qnzm/20081115/1226763989
ガベージコレクションのパフォーマンス
開始のために
- 全てのスレッドを一斉に一時停止し、スレッドがどこを実行しているか確認
- 全てのスレッドがセーブポイントに到達するか乗っ取りができたら、ガベージコレクションを開始できる。
ガベージコレクションの構成
- サーバモード(gcServer)
- CPUごとに一つのスレッド。
- それぞれのスレッドが他のスレッドと並列に自分の担当セクションの回収作業を実施。
- ASP.NETやSQL Serverなどのホストアプリケーションで利用
- gcConcurrent
- ガベージコレクションの同時実行(これはガベージコレクションの規定の動作)
- 同時実行用にバックグラウンドスレッドを持つ。
- 対話的処理のレスポンス向上
- パフォーマンス低下、またメモリの多量消費