ガベージコレクションの理解
概要
JVMにおけるガベージコレクション(GC)のトピックについて掘り下げてみましょう。
GCとは?
JVMのメモリは複数の領域に分かれています。
ヒープ領域は、new
などの操作で作成されたオブジェクトや配列が格納される場所です。ヒープ領域で作成されたオブジェクトや配列は他のオブジェクトから参照されることがあります。GC はまさにこのヒープ領域で行われます。
Javaプログラムが終了せずに実行を続けると、メモリにデータが蓄積され続けます。GCはこの問題を解決します。
どうやって解決するのでしょうか?JVMは到達不能なオブジェクトをGCの対象として識別します。どのオブジェクトが到達不能になるかを理解するためには、以下のコードを見てみましょう。
public class Main {
public static void main(String[] args) {
Person person = new Person("a", "すぐに参照されなくなる");
person = new Person("b", "参照が維持される");
}
}
person
が最初に初期化されると、作成されたa
は次の行でb
に再割り当てされ、到達不能なオブジェクトになります。次のGCでa
はメモリから解放されます。
ストップ・ザ・ワールド
ザ・ワールド!時よ止まれ! - ジョジョの奇妙な冒険
アプリケーションの実行を停止してGCを行います。「ストップ・ザ・ワールド」イベントが発生すると、GCを実行しているスレッド以外のすべてのスレッドが一時停止します。 GC操作が完了すると、一時停止していたタスクが再開されます。使用されるGCアルゴリズムに関係なく、「ストップ・ザ・ワールド」イベントは発生し、GCのチューニ ングは通常、この一時停止状態の時間を短縮することを目的としています。
Javaではプログラムコード内で明示的にメモリを解放することはありません。オブジェクトをnull
に設定して解放することは大きな問題ではありませんが、System.gc()
を呼び出すとシステムのパフォーマンスに大きな影響を与える可能性があり、絶対に使用すべきではありません。さらに、System.gc()
は実際にGCが発生することを保証しません。
GCが発生する2つの領域
Javaでは開発者が明示的にメモリを解放しないため、ガベージコレクタが不要になった(ガベージ)オブジェクトを識別して削除する役割を担います。ガベージコレクタは2つの主要な仮定に基づいて動作します:
- ほとんどのオブジェクトはすぐに到達不能になる。
- 古いオブジェクトから若いオブジェクトへの参照は非常に少ない。