.NET メモリ管理の概念
dotMemory を効果的に操作するには、.NET がメモリを管理する方法についての一般的な理解が必要です。このセクションでは、.NET メモリの概念についてまとめます。詳細については、Microsoft Learn または Web 上のその他の資料を参照してください。
メモリ割り当て
ガベージコレクタ(GC)は、.NET アプリケーションのメモリを割り当て、解放する .NET フレームワークの一部です。
新しいプロセスが開始されると、ランタイムはマネージヒープと呼ばれるプロセスのアドレス空間の領域を予約します。
オブジェクトは連続的にヒープ内に連続して割り当てられます。
メモリ割り当ては、ポインタに値を追加するだけなので、非常に高速な処理です。
マネージヒープに加えて、アプリは常に、GC によって管理されていない、いわゆるアンマネージド * メモリをある程度消費します。
メモリ解放
メモリを解放するプロセスはガベージコレクションと呼ばれます。
GC はコレクションを実行するときに、アプリケーションで使用されなくなったオブジェクトのみを解放します(たとえば、メソッドのローカル変数はメソッドの実行中にしかアクセスできず、その後はその変数は不要になります)。
オブジェクトが使用されているかどうかを判断するために、GC はアプリケーションのルート、つまりアプリケーションに対してグローバルな強力な参照を調べます。通常、これらはグローバルおよび静的オブジェクトポインタ、ローカル変数、CPU レジスタです。可能な GC ルートについては GC ルートの分析で学びましょう。
アクティブなルートごとに、GC はこれらのルートから到達可能なすべてのオブジェクトを含むグラフを作成します。
オブジェクトに到達できない場合、GC はそれが使用されなくなったとみなし、ヒープからオブジェクトを削除します(オブジェクトが占有するメモリを解放します)。
オブジェクトが削除されると、GC はメモリ内の到達可能なオブジェクトを圧縮します。
世代
メモリ解放のパフォーマンスを向上させるために、マネージヒープは世代と呼ばれるセグメント(0,1、および 2)に分割されています。
オブジェクトが作成されると、ジェネレーション 0(Gen 0)に配置されます。
Gen 0 がいっぱいになると(ヒープのサイズと世代は GC で定義されます)、GC はガベージコレクションを実行します。コレクション中、GC は到達不能オブジェクトをすべてヒープから削除します。到達可能なすべてのオブジェクトは、第 1 世代(Gen 1)に昇格されます。
Gen 0 コレクションはかなり簡単な操作です。
Gen 1 がいっぱいになると、Gen 1 ガベージコレクションが実行されます。コレクションに残っているすべてのオブジェクトは Gen 2 にプロモートされます。Gen 0 コレクションもここで行われます。
Gen 2 がいっぱいになると、GC は完全なガベージコレクションを実行します。まず、Gen 2 コレクションが実行され、その後、Gen 1 および Gen 0 コレクションが実行されます。それでも新しい割り当てに十分なメモリがない場合、GC は
OutOfMemory
例外を発生させます。完全なガベージコレクションの間、GC はヒープ内のすべてのオブジェクトを通過する必要があるため、このプロセスはシステムリソースに大きな影響を与える可能性があります。
ラージオブジェクトヒープ
パフォーマンス上の理由により、ラージオブジェクト(85 KB より大きい)は、ラージオブジェクトヒープ(LOH)と呼ばれるマネージヒープの別のセグメントに格納されます。
LOH で存続するオブジェクトは、圧縮された * ではありません。これは、LOH が時間の経過とともに断片化することを意味します。