Javaのsystem.gc()メソッドとfinalize()メソッドの間で混乱しています。ガベージオブジェクトをJVMに強制的に収集することはできません。 Javaコードで両方のメソッドを記述できます。両方がガベージコレクションに使用される場合、Javaによるガベージコレクションに2つのメソッドを提供する意味は何ですか?
両方の方法の正確な動作と、内部的にどのように動作するかを教えてください。
System.gc()
は親切にシステムにガベージコレクションを実行するように依頼します。 Javadocによると:
ガベージコレクターを実行します。
ガベージコレクタがどの程度「ハード」に機能するかを制御することはできません。ガベージコレクタが内部でどのように機能するかは、VM固有であり、それ自体が研究トピックです。しかし、通常は「完全な」ガベージコレクションといくつかの小さな「インクリメンタル」コレクションが進行中です。したがって、_System.gc
_を要求と見なしますが、オブジェクトのガベージコレクションが行われる保証はありません。
Object.finalize()
をオーバーライドして、特定のオブジェクトがガベージコレクションされたときに何をするか(実際には、ガベージコレクションされる直前に何をするか)を指定できます。 Javadocによると:
ガベージコレクションがオブジェクトへの参照がこれ以上ないと判断したときに、オブジェクトのガベージコレクターによって呼び出されます。
ファイナライザーの従来の使用法は、オブジェクトがガベージコレクションされたときにシステムリソースの割り当てを解除することです。リリースファイルハンドル、一時ファイルなど。
JVMの終了時に、ファイナライザーを使用してアクションを実行しないでください。この目的のために、Runtime.getRuntime().addShutdownHook(Thread)
に登録するシャットダウンフックを使用します。
System.gc()
はガベージコレクターを強制的に実行し、オブジェクトのFinalize()
メソッドは、この特定のオブジェクトを収集するときにガベージコレクターが実行する必要があることを定義します。
大まかに言えば、次のようになります。
class MyClass {
public UnmanagedResource resource;
void Finalize() {
FreeUnmanagedResource(resource);
}
}
MyClass[] data = new MyClass[1000];
for(int i=0; i<1000; i++) {
data[i] = new MyClass();
}
//do some work
data = null;
System.gc(); //Note that it doesn't guarantee you that all MyClass instances will be actually collected at this point.
system.gc()メソッドのガベージコレクションはnewキーワードによって作成されたオブジェクトを収集しますが、finalise()メソッドは、newキーワードを使用して作成されていないオブジェクトをガベージコレクションする場合に使用されます。だから、私はこれを推測します。あなたのQ
system.gc()
メソッドは、ガベージコレクターを実行して、未使用のオブジェクトを削除することでメモリをクリアできることをJVMに通知します。 Java docによると:
Gcメソッドを呼び出すと、Java仮想マシンは、現在占有しているメモリをすばやく再利用できるようにするために、未使用のオブジェクトのリサイクルに労力を費やしていることがわかります。制御がメソッド呼び出しから戻ると、Java仮想マシンは、破棄されたすべてのオブジェクトからスペースを再利用するために最善を尽くしました。
finalize()
メソッドは、ガベージコレクターをトリガーしません。代わりに、ガベージコレクターがオブジェクトを破棄している間に呼び出されます。オブジェクトを適切にクリアするための手順を提供します。
ここでの答えは素晴らしいですが、finalize()メソッドについて少し詳しく説明したかっただけです。絶対に使用しないでください。その実行はまったく保証されておらず、最終的にfinalize()を使用するとパフォーマンスが低下します。
ジョシュア・ブロックによるEffective Java)に書かれているように:
ファイナライザーは予測不可能で、多くの場合危険であり、通常は不要です。ファイナライザーでタイムクリティカルなことは絶対にしないでください。重要な永続状態を更新するためにファイナライザーに依存することはありません。
そして:
ああ、そしてもう1つ、ファイナライザーを使用するとパフォーマンスが大幅に低下します。私のマシンでは、単純なオブジェクトを作成して破棄する時間は約5.6nsです。ファイナライザーを追加すると、時間が2,400nsに増加します。つまり、ファイナライザーを使用してオブジェクトを作成および破棄するのは、約430倍遅くなります。
実行が保証されている、try-finallyパターンを終了する次のリソースを使用することをお勧めします。
Bar bar = new Bar(...);
try {
// Your code here
} finally {
bar.releaseResource(); // You implementation. For example close connection
}
ガベージコレクタは、任意のクラスでSystem.gc()
メソッドを呼び出すことによって呼び出されます。ただし、jvmがシャットダウンする前に、すべてのnullifiedオブジェクトがガベージコレクションされることを保証するものではありません。したがって、基本的にgc()
メソッドは、newキーワードを使用して作成されたオブジェクトのみをガベージコレクションします。オブジェクトは、これ以外のロジックによって作成され、gc
がガベージコレクターを呼び出す前にfinalize()
メソッドを明示的に呼び出すことによってガベージコレクションされます。
ガベージコレクションはオブジェクトの割り当てられたメモリを再利用するために使用され、Finalize()
はメモリを再利用する前にガベージコレクタによって呼び出されますFinalize()
メソッドは以前に何らかの操作を行うために主に使用されましたオブジェクトの削除
Finalize()メソッドを含むクラスはたくさんありますが、Objectクラスのクラスを意味していると思います。 System.gc()は、Javaのガベージコンパイラを実行するときに呼び出すものです。数分ごとに自動的に実行されますが、いつでも実行するように依頼できます。 gargabeコレクターが実行されると、参照がなくなった各オブジェクトでfinalize()メソッドが呼び出されます。基本的に、System.gc()はメモリをクリーンアップし、finalize()を使用して個々のオブジェクトを削除します。