アットウィキロゴ

マネージヒープとガベージコレクション

#contents

マネージヒープの基本

  • CLRではすべてのリソースはマネージヒープから割り当てられる。
  • ヒープ内で次にオブジェクトを割り当てる場所を示すポインター(NextObjPtr)を管理する
  • CLRはプロセスのアドレス空間が満杯になるまで領域を割り当てる(32bitでは1.5GB)

マネージヒープからリソースを割り当てる

  • 型のフィールドに必要なバイト数を計算する。
  • オブジェクトのオーバヘッドフィールドに必要なバイト数を計算する(32bitでは8byte,64bitでは16byte)。
  • 使用可能かどうかをCLRにて検査し、可能であればNextObjPtrにオブジェクトを格納する。ない場合はGCを呼ぶ
    • マネージヒープではオブジェクトの割り当てはポインターへの加算のみであり、非常に高速

GCのアルゴリズム

  • オブジェクトの生存期間を管理するために参照カウントを行う(参照カウントALG=循環参照時に問題あり)
  • 参照追跡型のアルゴリズムを使用する。
  • GCを開始すると、CLRはプロセス内のすべてのスレッドを停止する
    • ステートが変更されるのを防ぐためである
  • マーキングフェーズを開始する
    • 参照型の変数root(クラスの静的インスタンスフィールド、メソッドの引数などの総称)
    • rootがnullであるならばそのルートを無視し、次を検査する
  • コンパクションフェーズ
    • どのオブジェクトが生き残るか、削除するかを前フェーズで完了している
    • すべての生き残りオブジェクトをコンパクションしてメモリ上で連続するようにする =参照の局所性が上がる
    • このフェーズではオブジェクトのポインタが変わるため、アプリケーションがオブジェクトを参照できなくなる。
      • 参照先のオブジェクトがメモリ内で移動したバイト数を各ルートから引き算している
  • 重要
    • 静的フィールドは永久にまたは型がロードアプリケーションドメインがアンロードされるまで参照先のオブジェクトを保持する。
    • メモリリークが発生する主な原因はコレクションオブジェクトを参照する静的フィールドであり、コレクションオブジェクトに項目を追加したままになっていることである。
  • 世代別ガーベジコレクション

memo

  • IDisposableインターフェイスを実装する型を定義するときは

アプリケーションのメモリ使用量を確認

  • CollectionCount,GetTotalMemoryメソッドを使用
  • ネイティブリソースをラップするオブジェクトはほとんどメモリを占有しない
  • あるクラスをラップする場合、内部的にどれほどのメモリが使用されるかわからない。
    • AddMemoryPressure,RemoveMemoryPressureを使用することでランタイムが感知しないところでどれほどメモリが使われているかを教えてくれる。
最終更新:2015年08月10日 11:17