what is garbage collection java
このチュートリアルでは、Javaのガベージコレクションとは何か、およびガベージコレクターはどのように機能するかについて説明します。また、ガベージコレクションのアルゴリズムについても学習します。
C / C ++に精通している読者は、C / C ++でオブジェクトを作成および削除するのはプログラマーの責任であることを認識しておく必要があります。
プログラマーが作成されたオブジェクトを破棄するのを忘れると、重大なエラーが発生します。これは、オブジェクトの破棄に失敗すると、「 OutOfMemory 」エラー、メモリリークなど。
プログラマーがオブジェクトを追跡する必要がないため、この状況はJavaで完全に処理されます。 Javaは、自動ガベージコレクションを通じてオブジェクトの破棄を処理します。
=> ゼロからJavaを学ぶには、ここにアクセスしてください。
使用されなくなったオブジェクトがヒープメモリから削除されるプロセスは、「ガベージコレクション」と呼ばれます。ガベージコレクション手法は、Javaのメモリ管理の一部です。
したがって、Javaでは、ガベージコレクターは使用されなくなったすべてのオブジェクトを破棄します。
学習内容:
Javaのガベージコレクターとは何ですか?
Javaのガベージコレクションは、ガベージコレクタと呼ばれるプログラムによって管理されます。
ガベージコレクタは、オブジェクトの割り当て解除を処理することによってメモリを自動的に管理するために使用されるプログラムとして定義できます。
Java言語では、new演算子を使用して新しいオブジェクトが作成され、メモリが割り当てられることがわかっています。 new演算子を使用してオブジェクトに割り当てられたメモリは、参照がこのオブジェクトを使用するまで割り当てられたままになります。
参照が存在しなくなるとすぐに、オブジェクトが占有するメモリが再利用されます。その後、Javaはオブジェクトの割り当て解除または破棄を自動的に処理するため、オブジェクトを明示的に破棄する必要はありません。
この手法は、プログラマーがオブジェクトの割り当て解除を明示的に処理する必要がないJavaのガベージコレクション手法です。
オブジェクトがメモリを必要としないときにプログラムがメモリの割り当てを解除しない場合、最終的には割り当て可能なメモリがなくなり、プログラムがクラッシュすることに注意してください。この状況はメモリリークと呼ばれます。
ガベージコレクターは、常にデーモンスレッドのバックグラウンドで実行されます。ガベージコレクターは、デーモンスレッドの最良の例と見なされています。
ガベージコレクタは、ヒープメモリを解放することを目的として実行されます。これは、「到達不能」なオブジェクトを破棄することによって行われます。
「到達不能」オブジェクトとは何ですか?
オブジェクトに関連付けられた参照が1つもない場合、オブジェクトは到達不能になります。
次のコードについて考えてみます。
Integer ref_obj = new Integer (5); //ref_obj is a reference to Integer ref_obj = null; //Integer object now becomes unreachable
上記のコードからわかるように、参照が関連付けられている限り、オブジェクトに到達できます。参照の関連付けが削除されると(上記の場合は参照をnullに設定)、オブジェクトに到達できなくなります。
オブジェクトが到達不能になると、ガベージコレクション(GC)の対象になります。
オブジェクトをGCの対象にするにはどうすればよいですか?
プログラマーは、GCによって処理されるため、オブジェクトを破棄する必要はありませんが、少なくともプログラマーは、これらのオブジェクトが不要になったときに到達不能にすることができます。
これを行うことにより、GCは到達不能なオブジェクトを収集して破壊します。
オブジェクトを到達不能にすることにより、オブジェクトをGCの対象にする方法がいくつかあります。
彼らです:
#1)参照を無効にする
オブジェクトに割り当てられた参照が与えられ、このオブジェクトが不要になった場合は、参照をnullに割り当てます。
Student s = new Student (); s = null;
sがnullに設定されている場合、Studentオブジェクトは到達不能になります。
#2)参照を再割り当てする
これは、オブジェクトをGCの対象にするもう1つの方法です。
次のコードについて考えてみます。
Student s1 = new Student (); Student s2 = new Student (); s1 = s2;
s1を別のオブジェクトに割り当てたので、s1によって参照されるStudentオブジェクトは逆参照されます。
#3)匿名オブジェクトを作成する
匿名オブジェクトを作成することで、オブジェクトをGCの対象にすることができます。
以下に示すように、匿名オブジェクトを作成できます。
new Student();
オブジェクトをGCの対象にすると、これらのオブジェクトはGCによってすぐに破棄される場合とされない場合があります。これは、GCを必要なときに明示的に実行することができないためです。
ガベージコレクターはいつ実行されますか?
ガベージコレクタプログラムを実行するのはJVM次第です。 JVMがガベージコレクタを実行すると、到達不能なオブジェクトが破棄されます。ただし、それでも、JVMがいつ実行されるかを保証することはできません。
GCを強制的に実行することはできませんが、ガベージコレクションを要求することはできます。
GCは、次のいずれかの方法を使用して要求できます。
#1)System.gc(): JavaのSystemクラスは、静的メソッドgc()を提供します。これを使用して、JVMにガベージコレクターの実行を要求できます。
#2)Runtime.getRuntime()。gc(): System.gc()と同様に、「ランタイムクラス」のgc()メソッドを使用して、JVMにガベージコレクターの実行を要求することもできます。
注意: ガベージコレクターがこれら2つの方法からの要求の後に実行されるという保証はありません。
ファイナライズ
ファイナライズは、オブジェクトを破棄する直前にガベージコレクターによって実行されます。ファイナライズ手法の一部として、ガベージコレクターはオブジェクトのfinalize()メソッドを呼び出します。 finalize()メソッドは、クリーンアップアクティビティを実行するために使用されます。
finalize()メソッドは「Object」クラスによって提供され、次のプロトタイプがあります。
protected void finalize () throws Throwable
オブジェクトがガベージコレクションされるたびにfinalize()メソッドが呼び出されます
注意: ガベージコレクタは、newキーワードを使用して作成されたオブジェクトのみを収集します。他のオブジェクトの場合は、finalize()メソッドを使用してクリーンアップを実行する必要があります。
以下のプログラムは、Javaでの簡単なガベージコレクションを示しています。
class TestGC{ @Override // finalize method: called on object once // before garbage collecting it protected void finalize() throws Throwable { System.out.println('Garbage collector called'); System.out.println('Object garbage collected : ' + this); } } class Main{ public static void main(String args[]){ TestGC gc1=new TestGC(); TestGC gc2=new TestGC(); gc1 = null; //nullify gc1 System.gc(); //request for GC to run gc2 = null; //nullify gc2 Runtime.getRuntime().gc(); //request for GC to run } }
出力
上記のプログラムでは、クラスTestGCを作成しました。このクラスでは、finalize()メソッドをオーバーライドしました。次に、メインクラスで、TestGCクラスの2つのオブジェクトを作成します。まず、オブジェクトを無効にし、System.gc()を呼び出してガベージコレクターを要求します。
次に、2番目のオブジェクトを無効にし、メソッドRuntime.getRuntime.gc()を呼び出してガベージコレクターを要求します。出力には、finalizeメソッドの出力が2回表示され、ガベージコレクターが2回実行されたことを示しています。
注意: この出力が得られましたが、毎回同じ出力が得られるとは限りません。それは完全にJVMに依存します。
ガベージコレクションはJavaでどのように機能しますか?
このセクションでは、Javaでガベージコレクションがどのように機能するかを見ていきます。
ガベージコレクション中に、ガベージコレクターはヒープメモリを検索し、到達不能なオブジェクトに「マーク」を付けます。それからそれはそれらを破壊します。
ただし、オブジェクトの数が増えると問題が発生します。オブジェクトが増えると、到達不能なオブジェクトを探すためにガベージコレクションにかかる時間も長くなります。ただし、ほとんどのオブジェクトの寿命は短いため、あまり影響はありません。
上記の動作はと呼ばれます 「ジェネレーショナルガベージコレクション」 そして、JVMのパフォーマンスを向上させることになっています。このアプローチでは、ヒープスペース全体が、若い世代、古い世代または古い世代、および永続的な世代に分割されます。
#1)若い世代のヒープスペース: すべての新しいオブジェクトがこのスペースに作成されます。スペースがいっぱいになると、マイナーGCが実行され、すべての死んだオブジェクトが破壊されます。ほとんどのオブジェクトが死んでいるため、マイナーGCプロセスは高速です。若い世代を生き残ったオブジェクトは、古い世代に移動されます。
#2)旧世代のヒープスペース: この世代は、長期間存続するオブジェクトを格納します。若い世代に設定されたしきい値年齢に達すると、オブジェクトは古い世代に移動されます。古い世代のスペースがいっぱいになると、メジャーGCが実行されます。
ここに含まれるオブジェクトはライブオブジェクトであるため、メジャーGCは低速です。時々、若い世代と古い世代を含むヒープスペース全体がクリアされます。これは「フルGC」と呼ばれます。
#3)パーマネントジェネレーションL Java 7までは、Permanent Generation(Perm Gen)がありました。 PermGenが保持するメタデータはJVMによって使用されました。 JVMはこのメタデータを使用して、アプリケーションで使用されるクラスとメソッドを記述しました。 PermGenはJava8で削除されました。
Java 8ガベージコレクション:PermGenとMetaspace
Java7まで存在していたPermGenスペースについてはすでに説明しましたが、現在Java 8では、JVMは「メタスペース」と呼ばれるネイティブメモリを使用してクラスメタデータを表します。
Metaspaceとは別に、クラスメタデータに使用されるメモリを制限する「MaxMetaspaceSize」と呼ばれる新しいフラグがあります。 MaxMetaspaceSizeに値が指定されていない場合、メタスペースはアプリケーションの要求に応じて実行時にサイズを変更します。
クラスメタデータスペースがMaxMetaspaceSizeに達すると、メタスペースGCがトリガーされます。 Metaspace GCが多すぎる場合は、クラス、クラスローダーなどのメモリリーク、および不適切なサイズ設定を示しています。
Javaでのガベージコレクションアルゴリズム
ガベージコレクションはさまざまな方法で実行されます。このセクションでは、Javaでのガベージコレクションのための4つのそのような方法またはアルゴリズムを紹介します。
シリアルGC
シリアルGCは、最も単純なGCアルゴリズムです。これは主に、小さなヒープサイズとシングルスレッドシステムで機能します。動作中、SerialGCはすべてのアプリケーションをフリーズします。
シリアルGCをオンにするには、次のJVMオプションを使用できます。
YouTubeプレイリストからすべての曲をダウンロード
java –xx:+UseSerialGC –jar Application.java
上記のコマンドは、コマンドラインで指定できます。ここで、Application.javaは、シリアルGCを有効にするファイルです。
スループット/パラレルGC
並列GCアルゴリズムは、JDK 8のデフォルトのアルゴリズムです。このアルゴリズムは、複数のスレッドを使用してヒープスペースと圧縮をスキャンします。このアルゴリズムは、スレッドの一時停止を処理し、CPUオーバーヘッドを最適化できるアプリケーションに主に適しています。
並列GCの欠点の1つは、マイナーまたはフルGCの実行中に、アルゴリズムがアプリケーションスレッドを一時停止することです。
CMSコレクター
CMSは「 コンカレントマークスイープ 」。このアルゴリズムは複数を利用します 同時 ヒープをスキャンするスレッド( マーク )未使用のオブジェクトを識別してリサイクルする( 掃く )それら。 CMSコレクターには、Stop-The-World(STW)モードがあります。
コレクターは、次の2つのシナリオでこのモードになります。
- 静的変数またはスレッドエントリポイントから旧世代に属するオブジェクトに到達できる場合。したがって、このモードは、初期ルートマーキングの初期化中にオンになります。
- アルゴリズムが同時に実行されている場合、アプリケーションは状態を変更し、コレクターを強制的に戻して、正しいオブジェクトがマークされていることを確認します。
ただし、CMSコレクターは「プロモーションの失敗」に悩まされる可能性があります。では、プロモーションの失敗とは何ですか?若い世代のスペースのオブジェクトが古い世代に移動され、コレクターが古い世代のヒープスペースにこれらのオブジェクト用の十分なスペースを作成していない場合、プロモーションの失敗が発生します。
プロモーションの失敗を防ぐために、コレクターにより多くのバックグラウンドスレッドを提供するか、古い世代により多くのヒープサイズを提供する場合があります。
G1コレクター
G1コレクターは、「ガベージファースト」コレクターです。 4GBを超えるヒープサイズ用に設計されています。ヒープサイズに基づいて、ヒープサイズを1MBから32MBの範囲のサイズの領域に分割します。
G1コレクターは、ヒープ全体のオブジェクトの活気に応じてオブジェクトにマークを付けます。このマーキング段階の後、G1は空の領域を認識します。したがって、これらの領域から到達不能なオブジェクトを収集し、それによって大量のスペースを解放します。したがって、最初にガベージを含む領域を収集するため、ガベージファーストと呼ばれます。
また、指定された一時停止時間の目標に応じて収集する領域の数を選択することにより、一時停止予測モデルを使用して、ユーザー定義の一時停止時間の目標を満たします。
ガベージコレクションの利点
- ガベージコレクションは、プログラマーの介入なしにヒープメモリから参照されていないオブジェクトを削除するため、Javaでのメモリ管理を効率的にします。
- ガベージコレクションは自動でJVMの一部であるため、メモリを再利用したりオブジェクトを破棄したりするためにプログラマーが特別な作業を行う必要はありません。
- プログラマは、C / C ++で行われているように、メモリの割り当てを解除してオブジェクトを削除するための特定のコードを記述する必要はありません。
よくある質問
Q#1)ガベージコレクターの役割は何ですか?
回答: Javaでは、ガベージコレクターはメモリ管理のメインパーティであり、到達不能なオブジェクトを収集してメモリを再利用する役割を果たします。
Q#2)ガベージコレクションとはどういう意味ですか?
回答: ガベージコレクションは、未使用のメモリを再利用することでメモリを自動的に管理する手法です。これは、Javaなどのプログラミング言語に存在する機能であるため、プログラマーは未使用のオブジェクトを追跡して破棄する必要がありません。ガベージコレクションを使用して自動的に実行されます。
Q#3) Javaでのガベージコレクションの責任者は誰ですか?
回答: Javaのメモリ管理には、ガベージコレクションの責任があります。
Q#4) Javaでガベージコレクションを防ぐにはどうすればよいですか?
回答: ガベージコレクターは生きている変数/オブジェクトのメモリを再利用しないため、ガベージコレクションを防ぐ最善の方法は、プログラム全体で変数/オブジェクトを使い続けることです。
Q#5) オブジェクトがガベージコレクションされていることをどのように確認できますか?
回答: オブジェクトが到達不能な場合、つまり、オブジェクトを参照している参照がなくなった場合、オブジェクトはガベージコレクションの対象になります。ガベージコレクターをいつでも強制的に実行することはできませんが、System.gc()を使用していつでも実行を要求できます。
結論
このチュートリアルで説明したJavaのガベージコレクションは自動であり、プログラマーはプログラムに割り当てられたオブジェクトや変数の削除について自分で心配する必要はありません。
Javaでの自動ガベージコレクションは、この言語の最も重要な機能であり、Javaのメモリ管理の一部です。
ガベージコレクションはJVMによって実行され、プログラマーの手の届かないところにありますが、システムクラスとランタイムクラスのgc()メソッドを使用して、ガベージコレクターの実行をいつでも要求できます。
このチュートリアルでは、ガベージコレクターによってオブジェクトが破棄される前に実行されるファイナライズプロセスについて説明しました。また、Javaでのガベージコレクションのプロセスについても説明しました。最後に、ガベージコレクターで使用されるさまざまなアルゴリズムについて説明しました。
これで、Javaのガベージコレクタに関する説明は終わりです。
=> ここで簡単なJavaトレーニングシリーズに注意してください。