私はJavaが初めてで、Javaのガベージコレクターについて混乱しています。実際に何をするのか、いつ実行されるのか。 Javaでガベージコレクターのプロパティのいくつかを説明してください。
ガベージコレクター は Java仮想マシン で実行されるプログラムで、Javaアプリケーションで使用されなくなったオブジェクトを取り除きます。これは、自動メモリ管理の形式です。
一般的なJavaアプリケーションが実行されている場合、String
sやFile
sなどの新しいオブジェクトが作成されますが、一定の時間が経過すると、それらのオブジェクトは使用されなくなります。たとえば、次のコードを見てください。
for (File f : files) {
String s = f.getName();
}
上記のコードでは、for
ループの各反復でString s
が作成されています。つまり、すべての反復で、String
オブジェクトを作成するために少しのメモリが割り当てられます。
コードに戻ると、1回の反復が実行されると、次の反復で、以前の反復で作成されたString
オブジェクトが使用されなくなっていることがわかります。 「。
最終的には、大量のゴミを取得し始め、使用されなくなったオブジェクトにはメモリが使用されます。この状態が続くと、最終的にJava仮想マシンのスペースが不足して新しいオブジェクトが作成されます。
そこでガベージコレクターが介入します。
ガベージコレクターは、もう使用されていないオブジェクトを探し、それらを取り除き、他の新しいオブジェクトがそのメモリを使用できるようにメモリを解放します。
Javaでは、メモリ管理はガベージコレクタによって処理されますが、Cなどの他の言語では、 malloc
やfree
などの関数を使用して独自にメモリ管理を実行する必要があります 。 メモリ管理 は、ミスを犯しやすいものの1つで、いわゆる呼び出しにつながる可能性があります メモリリーク -使用していないときにメモリが回収されない場所もう使用します。
ガベージコレクションなどの自動メモリ管理スキームにより、プログラマはメモリ管理の問題についてそれほど心配する必要がなくなるため、開発に必要なアプリケーションの開発に集中できます。
プログラムによって使用されなくなったオブジェクトに割り当てられたメモリを解放します-したがって、「ガベージ」という名前になります。例えば:
public static Object otherMethod(Object obj) {
return new Object();
}
public static void main(String[] args) {
Object myObj = new Object();
myObj = otherMethod(myObj);
// ... more code ...
}
これは非常に不自然であることがわかっていますが、ここでotherMethod()
を呼び出した後、作成された元のObject
は到達不能になります。これがガベージコレクションを行う「ガベージ」です。
JavaではGCが自動的に実行されますが、 System.gc()
およびtry to強制的にメジャーガベージコレクションで明示的に呼び出すこともできます。 Pascal Thiventが指摘しているように、あなたは本当にこれを行う必要はありません、それは良いことよりも害を及ぼす可能性があります( この質問 を参照)。
詳細については、ウィキペディアのエントリ Garbage collection および Tuning Garbage Collection (Oracleから)を参照してください。
オブジェクトは、ライブスレッドまたは静的参照から到達できない場合、ガベージコレクションまたはGCの対象になります。
つまり、すべての参照がnullの場合、オブジェクトはガベージコレクションの対象になると言えます。循環依存関係は参照としてカウントされないため、オブジェクトAがオブジェクトBへの参照を持ち、オブジェクトBがオブジェクトAへの参照を持ち、他のライブ参照がない場合、オブジェクトAとBの両方がガベージコレクションの対象になります。
ガベージコレクションのヒープ生成-
JavaオブジェクトはHeap
で作成され、Heap
はJavaのガベージコレクションのために3つの部分または世代に分割され、これらは若い(新しい)世代、Tenured(古い)世代、およびヒープのPerm Area。
New Generationは、Edenスペース、Survivor 1およびSurvivor 2スペースとして知られる3つの部分にさらに分割されます。ヒープで最初に作成されたオブジェクトは、エデン空間内の新しい世代で作成され、オブジェクトが生き残った場合、後続のマイナーガベージコレクションの後、メジャーガベージコレクションがそのオブジェクトを古い世代または終身世代。
Javaのパーマスペースヒープは、JVMがクラスとメソッド、文字列プール、およびクラスレベルの詳細に関するメタデータを格納する場所です。
詳細については、こちらを参照してください。 ガベージコレクション
System.gc()
またはRuntime.gc()
メソッドを使用してリクエストを行うことはできますが、JVMに強制的にガベージコレクションを実行させることはできません。
public static void gc() {
Runtime.getRuntime().gc();
}
public native void gc(); // note native method
マークアンドスイープアルゴリズム-
これは、ガベージコレクションで使用される最も一般的なアルゴリズムの1つです。ガベージコレクションアルゴリズムは、2つの基本操作を実行する必要があります。 1つは、到達不能なオブジェクトをすべて検出できる必要があり、2つ目は、ガベージオブジェクトが使用するヒープスペースを再利用し、そのスペースをプログラムで再び使用可能にする必要があることです。
上記の操作は、マークアンドスイープアルゴリズムによって2つのフェーズで実行されます。
詳細については、こちらをお読みください- マークアンドスイープアルゴリズム
ガベージコレクターは、プログラムで不要になったオブジェクトが「ガベージ」であり、破棄できることを意味します。
ガベージコレクターはJREの一部であり、参照されていないオブジェクトをメモリから確実に解放します。
通常、アプリのメモリが不足すると実行されます。知る限りでは、オブジェクト間のリンクを表すグラフを保持しており、孤立したオブジェクトを解放できます。
[。 GCが実行されるたびにすべてのオブジェクトがスキャンされるわけではありません。
read this 詳細については。
多くの人は、ガベージコレクションが死んだオブジェクトを収集して破棄すると考えています。
実際には、Javaガベージコレクションはその逆です!ライブオブジェクトは追跡され、他のすべてはゴミとして指定されます。
オブジェクトが使用されなくなると、ガベージコレクターは基になるメモリを再利用し、将来のオブジェクト割り当てに再利用します。これは、明示的な削除がなく、オペレーティングシステムにメモリが戻されないことを意味します。使用されなくなったオブジェクトを判別するために、JVMは非常に適切にマークアンドスイープアルゴリズムと呼ばれるものを断続的に実行します。
詳細情報については、これを確認してください: http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx
ガベージコレクターを使用すると、コンピューターは無限のメモリを持つコンピューターをシミュレートできます。 残りは単なるメカニズムです。
これは、コードからメモリチャンクにアクセスできなくなったことを検出し、それらのチャンクをフリーストアに返すことによって行われます。
編集:はい、リンクはC#用ですが、C#とJavaはこの点で同一です。
プログラマーでなくても理解できる最も簡単な言葉で言えば、プログラムがデータを処理するとき、そのデータの中間データとストレージスペース(変数、配列、特定のオブジェクトメタデータなど)を作成します。
これらのオブジェクトが機能間または特定のサイズを超えてアクセスされると、それらは中央ヒープから割り当てられます。その後、それらが不要になったら、クリーンアップする必要があります。
これがどのように機能するかについての非常に優れた記事がオンラインでいくつかありますので、非常に基本的な定義だけを取り上げます。
GCは、基本的にこのクリーンアップを行う関数です。これを行うには、アクティブなオブジェクトによって参照されていないテーブルエントリをクリアし、メモリをコピーして圧縮するよりも、オブジェクトを効果的に削除します。これよりも少し複雑ですが、アイデアは得られます。
大きな問題は、このプロセスがJava VM全体を一時的に停止する必要があり、このプロセス全体が非常にプロセッサとメモリの帯域幅に集中することを必要とする部分です。 GCのさまざまなオプションとそれぞれのチューニングオプションは、これらのさまざまな問題とGCプロセス全体のバランスをとるように設計されています。
ガベージコレクターは、参照カウントマネージャーとして表示できます。オブジェクトが作成され、その参照が変数に格納されている場合、その参照カウントは1つ増加します。その変数にNULLが割り当てられている場合、実行中に。そのオブジェクトの参照カウントは減少します。そのため、オブジェクトの現在の参照カウントは0です。ガーベッジコレクターが実行されると、参照カウント0のオブジェクトをチェックし、それに割り当てられたリソースを解放します。
ガベージコレクタの呼び出しは、ガベージコレクションポリシーによって制御されます。
ここでいくつかのデータを取得できます。 http://www.Oracle.com/technetwork/Java/gc-tuning-5-138395.html
ガベージコレクションの基本原則は、将来アクセスできないプログラム内のデータオブジェクトを見つけ、それらのオブジェクトが使用するリソースを再利用することです。 https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29
利点
1)バグへの保存。これは、メモリへのポインタがまだある間にメモリの一部が解放され、それらのポインタの1つが逆参照されるときに発生します。 https://en.wikipedia.org/wiki/Dangling_pointer
2)二重解放バグ。これは、プログラムがすでに解放されているメモリ領域を解放しようとしたときに発生し、おそらく再び割り当てられた場合に発生します。
3)特定の種類のメモリリークを防ぎます。このリークでは、プログラムは、到達不能になったオブジェクトによって占有されているメモリを解放できず、メモリの枯渇を招く可能性があります。
欠点
1)追加のリソースの消費、パフォーマンスへの影響、プログラム実行の停止の可能性、および手動のリソース管理との非互換性。プログラマが既にこの情報を知っている場合でも、ガベージコレクションは、どのメモリを解放するかを決定する際にコンピューティングリソースを消費します。
2)ガベージが実際に収集される瞬間は予測不能である可能性があり、その結果、セッション中にストール(シフト/メモリの解放の一時停止)が散在します。予測不能なストールは、リアルタイム環境、トランザクション処理、または対話型プログラムでは受け入れられない可能性があります。
Oracleチュートリアル http://www.Oracle.com/webfolder/technetwork/tutorials/obe/Java/gc01/index.html
ガベージコレクションは、使用されているオブジェクトと使用されていないオブジェクトを識別し、未使用のオブジェクトを削除するプロセスです。
C、C++などのプログラミング言語では、メモリの割り当てと解放は手動プロセスです。
int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory
プロセスの最初のステップはマーキングと呼ばれます。これは、ガベージコレクターが使用中のメモリピースと使用していないメモリピースを識別する場所です。
ステップ2a。通常の削除では、参照されていないオブジェクトが削除され、参照されたオブジェクトと空き領域へのポインタが残ります。
パフォーマンスを向上させるために、参照されていないオブジェクトを削除し、残りの参照されているオブジェクトを圧縮します。参照されるオブジェクトを一緒に保持したいので、新しいメモリを割り当てる方が速くなります。
前述のように、JVM内のすべてのオブジェクトをマークして圧縮することは非効率的です。より多くのオブジェクトが割り当てられると、オブジェクトのリストが大きくなり、ガベージコレクション時間がますます長くなります。
このチュートリアルを読み続けると、GCがこの課題にどのように対処するかがわかります。
つまり、ヒープには3つの領域があります。短命オブジェクトの場合はYoungGeneration、OldGeneration長期間のオブジェクトの場合、およびPermanentGenerationアプリケーションの存続期間中に存在するオブジェクト(クラス、ライブラリなど)の場合。
ガベージコレクションとは、プログラムでアクセスできなくなったオブジェクトを削除することにより、ヒープ上のメモリを自動的に解放するプロセスのことです。ヒープは、フリーストアと呼ばれるメモリであり、Javaアプリケーションに割り当てられた未使用メモリの大きなプールを表します。
自動ガベージコレクションは、ヒープメモリを調べ、使用中のオブジェクトと使用していないオブジェクトを特定し、未使用のオブジェクトを削除するプロセスです。使用中のオブジェクト、または参照オブジェクトとは、プログラムの一部がまだそのオブジェクトへのポインターを保持していることを意味します。未使用のオブジェクト、または参照されていないオブジェクトは、プログラムのどの部分からも参照されなくなりました。そのため、参照されていないオブジェクトが使用しているメモリを再利用できます。
Cのようなプログラミング言語では、メモリの割り当てと割り当て解除は手動プロセスです。 Javaでは、メモリの割り当て解除プロセスはガベージコレクターによって自動的に処理されます。より良い理解のためにリンクをチェックしてください。 http://www.Oracle.com/webfolder/technetwork/tutorials/obe/Java/gc01/index.html
ガベージコレクターはjvmのコンポーネントです。
CPUが解放されたときにゴミを収集するために使用されます。
ここで、ガベージとは、メインプログラムのバックグラウンドで実行される未使用オブジェクトを意味します
メインプログラムのステータスを監視します。
オブジェクトはnew演算子によって動的に割り当てられるため、これらのオブジェクトがどのように破棄され、ビジーなメモリがどのように解放されるかを尋ねることができます。 C++などの他の言語では、delete演算子によって手動で割り当てられたオブジェクトを動的に解放する必要があります。 Javaには異なるアプローチがあります。割り当て解除を自動的に処理します。この手法はGarbage Collectionとして知られています。
これは次のように機能します。オブジェクトへの参照がない場合、このオブジェクトは不要になり、オブジェクトが占有しているメモリを取得できると想定されます。 C++のようにオブジェクトを明示的に破棄する必要はありません。ガベージコレクションは、プログラムの実行中に散発的に発生します。使用されなくなったオブジェクトが1つ以上あるため、単純に発生しません。さらに、いくつかのJavaランタイム実装にはガベージコレクションへのさまざまなアプローチがありますが、ほとんどのプログラマーはプログラムを書くときにこれを心配する必要はありません。
Java(および他の言語/プラットフォーム)のガベージコレクションは、Javaランタイム環境(JRE)がJavaオブジェクトからメモリを再利用する方法です。もはや必要ありません。簡単に言えば、JREは最初の起動時にオペレーティングシステム(O/S)に一定量のメモリを要求します。 JREはアプリケーションを実行するときに、そのメモリを使用します。アプリケーションがそのメモリを使用して完了すると、JREの「ガベージコレクタ」が現れ、既存のアプリケーションのさまざまな部分で使用するためにそのメモリを回収します。 JREの「ガベージコレクター」は、常に実行されているバックグラウンドタスクであり、システムがガベージランを実行するためにアイドル状態の時間を選択しようとします。
現実世界の例えは、ごみの男性があなたの家に来てあなたのリサイクル可能なごみを拾うことです...最終的に、それはあなた自身や他の人々によって他の方法で再利用されます。