Java仮想マシン-ガベージコレクション
JavaオブジェクトのライフサイクルはJVMによって管理されます。プログラマーがオブジェクトを作成したら、残りのライフサイクルについて心配する必要はありません。JVMは、使用されなくなったオブジェクトを自動的に検出し、ヒープからメモリを再利用します。
ガベージコレクションはJVMが実行する主要な操作であり、ニーズに合わせてガベージコレクションを調整すると、アプリケーションのパフォーマンスが大幅に向上します。最新のJVMによって提供されるさまざまなガベージコレクションアルゴリズムがあります。使用するアルゴリズムを決定するために、アプリケーションのニーズを認識する必要があります。
CやC ++などの非GC言語で行うことができるように、Javaでプログラムによってオブジェクトの割り当てを解除することはできません。したがって、Javaでぶら下がっている参照を持つことはできません。ただし、null参照(JVMがオブジェクトを格納しないメモリ領域を参照する参照)がある場合があります。null参照が使用されると、JVMはNullPointerExceptionをスローします。
GCのおかげでJavaプログラムでメモリリークが見つかることはめったにありませんが、実際に発生することに注意してください。この章の終わりにメモリリークを作成します。
次のGCは最新のJVMで使用されています
- シリアルコレクター
- スループットコレクター
- CMSコレクター
- G1コレクター
上記の各アルゴリズムは同じタスクを実行します。つまり、使用されなくなったオブジェクトを検索し、それらがヒープ内で占有しているメモリを再利用します。これに対する単純なアプローチの1つは、各オブジェクトが持つ参照の数をカウントし、参照の数が0になるとすぐにそれを解放することです(これは参照カウントとも呼ばれます)。なぜこれはナイーブなのですか?循環リンクリストについて考えてみましょう。各ノードにはそのノードへの参照がありますが、オブジェクト全体はどこからも参照されていないため、理想的には解放する必要があります。
JVMはメモリを解放するだけでなく、小さなメモリチャックを大きなメモリチャックに統合します。これは、メモリの断片化を防ぐために行われます。
簡単に言うと、典型的なGCアルゴリズムは次のアクティビティを実行します-
- 未使用のオブジェクトを見つける
- ヒープ内で占有しているメモリを解放する
- フラグメントの合体
GCは、実行中にアプリケーションスレッドを停止する必要があります。これは、実行時にオブジェクトを移動するため、それらのオブジェクトを使用できないためです。このような停止は「世界を停止する一時停止」と呼ばれ、これらの一時停止の頻度と期間を最小限に抑えることが、GCを調整する際の目標です。
メモリ合体
メモリ合体の簡単なデモンストレーションを以下に示します
影付きの部分は、解放する必要があるオブジェクトです。すべてのスペースが再利用された後でも、最大サイズ= 75Kbのオブジェクトしか割り当てることができません。これは、以下に示すように、200Kbの空き容量があった後でも発生します。