私はJavaに不慣れで、Javaのガベージコレクターについて混乱しています。実際に何をするのか、いつ実行されるのか。Javaのガベージコレクターのプロパティのいくつかを説明してください。
私はJavaに不慣れで、Javaのガベージコレクターについて混乱しています。実際に何をするのか、いつ実行されるのか。Javaのガベージコレクターのプロパティのいくつかを説明してください。
回答:
ガベージコレクタは、上で動作するプログラムであるJava仮想マシンもはやJavaアプリケーションで使用されていないオブジェクトを取り除きます。これは、自動メモリ管理の形式です。
典型的なJavaアプリケーションの実行中は、String
sやFile
s などの新しいオブジェクトが作成されますが、一定の時間が経過すると、それらのオブジェクトは使用されなくなります。たとえば、次のコードを見てください。
for (File f : files) {
String s = f.getName();
}
上記のコードでString s
は、for
ループの各反復でが作成されています。つまり、すべての反復で、String
オブジェクトを作成するために少しのメモリが割り当てられます。
コードに戻ると、単一の反復が実行されると、次の反復では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()
し、しようとする主要なガベージコレクションを強制します。Pascal Thiventが指摘しているように、これを行う必要はありませんし、害があるかもしれません(この質問を参照)。
詳細については、ガベージコレクションとチューニングガベージコレクション(Oracleから)に関するウィキペディアのエントリを参照してください。
System.gc()
はGCの実行を強制しません。
myObj
呼び出しotherMethod
が行われる前にGCが破棄されることは完全に有効であることに注意してくださいmyObj
。
System.gc()
、GCを持つことのすべてのポイントはそれをする必要がないことです。
オブジェクトは、ライブスレッドまたは静的参照から到達できない場合、ガベージコレクションまたはGCの対象になります。
つまり、すべての参照がnullの場合、オブジェクトはガベージコレクションの対象になると言えます。循環依存関係は参照としてカウントされないため、オブジェクトAにオブジェクトBへの参照があり、オブジェクトBにオブジェクトAへの参照があり、他にライブ参照がない場合、オブジェクトAとBの両方がガベージコレクションの対象になります。
ガベージコレクションのヒープ生成-
Javaオブジェクトは、Javaでのガベージコレクションのために作成されHeap
、Heap
3つの部分または世代に分割されます。これらは、ヒープのYoung(New)世代、Tenured(Old)世代、およびPerm Areaと呼ばれます。
ニュージェネレーションはさらに、エデンスペースとして知られるサバイバー1とサバイバー2の3つの部分に分かれています。ヒープで最初に作成されたオブジェクトがエデン空間内の新しい世代で作成された後、その後のマイナーガベージコレクションの後でオブジェクトが存続すると、メジャーガベージコレクションがそのオブジェクトを古い世代または古い世代に移動する前に、サバイバー1に移動し、次にサバイバー2に移動します。
Javaヒープのパーマスペースは、JVMがクラスとメソッド、文字列プール、クラスレベルの詳細に関するメタデータを格納する場所です。
詳しくはこちらをご覧ください:ガベージコレクション
System.gc()
またはRuntime.gc()
メソッドを使用してリクエストを行うことはできますが、JVMにガベージコレクションを実行させることはできません。
public static void gc() {
Runtime.getRuntime().gc();
}
public native void gc(); // note native method
マークアンドスイープアルゴリズム-
これは、ガベージコレクションで使用される最も一般的なアルゴリズムの1つです。ガベージコレクションアルゴリズムは、2つの基本的な操作を実行する必要があります。1つは、到達できないすべてのオブジェクトを検出できること、もう1つは、ガベージオブジェクトによって使用されているヒープスペースを再利用して、プログラムが再びスペースを利用できるようにすることです。
上記の操作は、マークアンドスイープアルゴリズムによって2つのフェーズで実行されます。
詳細については、こちらをご覧ください- マークアンドスイープアルゴリズム
ガベージコレクターは、参照されていないオブジェクトがメモリから解放されるようにするJREの一部です。
通常、アプリがメモリ不足になると実行されます。AFAIKは、オブジェクトと分離されたオブジェクトとの間のリンクが解放されることを表すグラフを保持しています。
世代にグループ化された現在のオブジェクトのパフォーマンスを節約するために、GCがオブジェクトをスキャンし、そのオブジェクトがまだ参照されていることを検出するたびに、1ずつインクリメントして(最大数の最大値、3または4と思います)、新しい世代が最初にスキャンされます(メモリ内のオブジェクトが最短であるほど、不要になる可能性が高い)したがって、GCが実行されるたびにすべてのオブジェクトがスキャンされるわけではない。詳細について
は、こちらをお読みください。
ガベージコレクターを使用すると、コンピューターは無限メモリを備えたコンピューターをシミュレートできます。残りは単なるメカニズムです。
これは、メモリのチャンクがコードからアクセスできなくなったことを検出し、それらのチャンクを空きストアに返すことによって行われます。
編集:はい、リンクはC#用ですが、C#とJavaはこの点で同一です。
多くの人は、ガベージコレクションは死んだオブジェクトを収集して破棄すると考えています。
実際には、Javaガベージコレクションはその逆です。ライブオブジェクトが追跡され、その他はすべてゴミを指定します。
オブジェクトが使用されなくなると、ガベージコレクターは基になるメモリを再利用し、将来のオブジェクトの割り当てに再利用します。これは、明示的な削除がなく、オペレーティングシステムにメモリが戻されないことを意味します。使用されなくなったオブジェクトを判別するために、JVMはマークアンドスイープアルゴリズムと呼ばれるものを断続的に実行します。
詳細については、こちらを確認してください:http : //javabook.compuware.com/content/memory/how-garbage-collection-works.aspx
プログラマーではない人でも理解できる最も簡単な言葉で言えば、プログラムがデータを処理すると、そのデータの中間データとストレージスペース(変数、配列、特定のオブジェクトメタデータなど)が作成されます。
これらのオブジェクトが関数間または特定のサイズを超えてアクセスされると、中央のヒープから割り当てられます。次に、それらが不要になったときに、クリーンアップする必要があります。
これがどのように機能するかについて、いくつかの非常に良い記事がオンラインにありますので、私は非常に基本的な定義をカバーします。
GCは基本的にこのクリーンアップを行う関数です。これを行うには、アクティブなオブジェクトによって参照されていないテーブルエントリをクリアし、オブジェクトを効果的に削除します。その後、メモリをコピーして圧縮します。これは少し複雑ですが、アイデアはわかります。
大きな問題は、このプロセスの多くの場合、このプロセスを実行するためにJava VM全体を一時的に停止する必要があり、このプロセス全体が非常にプロセッサとメモリの帯域幅を大量に消費することです。GCのさまざまなオプションとそれぞれのチューニングオプションは、GCプロセス全体でこれらのさまざまな問題のバランスを取るように設計されています。
Java(および他の言語/プラットフォーム)のガベージコレクションは、Javaランタイム環境(JRE)が不要になったJavaオブジェクトのメモリを再利用するための方法です。簡単に言うと、JREは最初の起動時にオペレーティングシステム(O / S)に一定量のメモリを要求します。JREがアプリケーションを実行すると、そのメモリが使用されます。アプリケーションがそのメモリを使用して完了すると、JREの「ガベージコレクター」が現れ、既存のアプリケーションのさまざまな部分で使用するためにそのメモリを再利用します。JREの「ガベージコレクター」は、常に実行されているバックグラウンドタスクであり、システムがアイドル状態のときにガベージランを実行する時間を選択しようとします。
現実の世界の例えは、あなたの家に来て、あなたのリサイクル可能なゴミを拾うゴミの男性です...最終的には、自分や他の人々によって他の方法で再利用されます。
ガベージコレクターは、参照カウントマネージャーと見なすことができます。オブジェクトが作成され、その参照が変数に格納されている場合、その参照カウントは1ずつ増加します。実行中にその変数にNULLが割り当てられている場合。そのオブジェクトの参照カウントは減少します。そのため、オブジェクトの現在の参照カウントは0です。ガベージコレクターが実行されると、参照カウント0のオブジェクトがチェックされ、それに割り当てられていたリソースが解放されます。
ガベージコレクターの呼び出しは、ガベージコレクションポリシーによって制御されます。
ここでデータを取得できます。 http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html
ガベージコレクターはjvmのコンポーネントです。
これは、CPUが解放されたときにゴミを収集するために使用されます。
ここでガベージとは、メインプログラムのバックグラウンドで実行される未使用のオブジェクトを意味します
メインプログラムのステータスを監視します。
自動ガベージコレクションは、ヒープメモリを調べて、使用中のオブジェクトと使用されていないオブジェクトを識別し、未使用のオブジェクトを削除するプロセスです。使用中のオブジェクトまたは参照されるオブジェクトは、プログラムの一部がまだそのオブジェクトへのポインタを保持していることを意味します。未使用のオブジェクトまたは参照されていないオブジェクトは、プログラムのどの部分からも参照されなくなりました。そのため、参照されていないオブジェクトが使用していたメモリを解放できます。
Cのようなプログラミング言語では、メモリの割り当てと割り当て解除は手動のプロセスです。Javaでは、メモリの割り当てを解除するプロセスは、ガベージコレクターによって自動的に処理されます。理解を深めるためにリンクを確認してください。 http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.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です。
オブジェクトは新しいオペレーターによって動的に割り当てられるため、これらのオブジェクトがどのように破棄され、ビジーなメモリがどのように解放されるかを確認できます。C ++などの他の言語では、手動で割り当てられたオブジェクトを削除演算子によって動的に解放する必要があります。Javaのアプローチは異なります。割り当て解除は自動的に処理されます。この手法は、ガベージコレクションと呼ばれます。
これは次のように機能します。オブジェクトへの参照がない場合、このオブジェクトは不要であると見なされ、オブジェクトが占有しているメモリを取得できます。C ++のようにオブジェクトを明示的に破棄する必要はありません。プログラムの実行中にガベージコレクションが散発的に発生します。使用されなくなったオブジェクトが1つ以上あるため、単に発生するわけではありません。さらに、いくつかのJavaランタイム実装ではガベージコレクションへのアプローチが異なりますが、ほとんどのプログラマはプログラムを作成するときにこれについて心配する必要はありません。
自動ガベージコレクションは、JVMが特定のデータポイントをメモリから削除または保持して、最終的に実行中のプログラムのためにスペースを解放するプロセスです。メモリは最初にヒープメモリに送信されます。つまり、ガベージコレクタ(GC)がその作業を行う場所であり、その後、終了または保持することが決定されます。Javaは、プログラマーが常に信頼できるとは限らないと想定しているため、不要と思われるアイテムを終了します。