System.gc()またはfinalize()メソッドが呼び出されたときに内部(JVM)で何が起こりましたか?
これは本当にゴミを収集するのですか、それともパフォーマンスを低下させるのですか?
System.gc()またはfinalize()メソッドが呼び出されたときに内部(JVM)で何が起こりましたか?
これは本当にゴミを収集するのですか、それともパフォーマンスを低下させるのですか?
System.gc()を呼び出したときに何が起こるかは、JVM に依存します。JVM はこの呼び出しを、ガベージコレクターを実行するのに適した時期である可能性があると見なすので、それに依存しないでください。
オブジェクトのfinalize()メソッドは、JVM がそのオブジェクトへの到達可能な参照がないと判断したときに、ガベージ コレクターによってそのオブジェクトに対して実行されます。コード内で呼び出すべきではありません。finalize() は、プログラムが最終参照を失った時点では呼び出されませんが、ガベージ コレクターが実行される将来の時点で呼び出されることに注意してください。そのため、特定の時点 (または全て)。
ガベージ コレクションの内部を知りたい場合は、Sun のHotspot Memory Management Whitepaperをお読みください。
System.gc()
名前が示すように、ガベージ コレクターを呼び出すことによって実行されます。この時点で、オブジェクトが実際に削除さfinalize()
れると、これらのオブジェクトが消える前に が呼び出されます。
最後の質問には " or
" を含めないでください。ガベージ コレクションとパフォーマンスの低下です。
gc
それはあなたにとって本当に良い仕事をするので、通常はまったく気にするべきではありません. 特定の時点で多くのオブジェクトを削除したい使用シナリオがあります。それなら実現可能です。
System.gc() はメモリをクリーンアップし、finalize() を使用して個々のオブジェクトを取り除きます。
finalize() は、オブジェクトがガベージ コレクションの準備が整う直前 (オブジェクトに強い参照がない場合) に、コードの最後のビットを実行する手段です。
では、いつ使用する必要がありますか?現在の 2 つの場合のみ:
上記の 2 つのケース以外では、決して使用しないでください。理由を理解するには?オブジェクトの機能とライフサイクルを理解する必要があります。
はじめに: finalize() メソッドの呼び出しを担当するファイナライザー スレッドと呼ばれる別のデーモン スレッドがあります。ファイナライズ キューは、finalize() メソッドを呼び出す準備が整ったオブジェクトが配置されるキューです。
オブジェクトがガベージ コレクションの準備ができると、ガベージ コレクタ スレッドは、この特定のオブジェクトに (1) で説明したテーブルからの finalize() があるかどうかをチェックします。
2a) そうでない場合は、ガベージ コレクションに送信されます。
2b) 持っている場合は、ファイナライズ キューに追加されます。そして、テーブルからオブジェクトのエントリを削除します (1)。
ファイナライザー スレッドはキューをポーリングし続けます。キュー内のすべてのオブジェクトに対して、その finalize() メソッドが呼び出されます。(2) からの finalize() サイクルを呼び出した後、再び繰り返されます。このオブジェクトがまだ強い参照を持っていない場合は、GC に送信されます。存在する場合は、(2b) でエントリが削除されたため、ALWAYS (2a) が呼び出されます。
Basically finalize() method is only called once.
では、上記のサイクルの問題は何でしょうか?
(1)より。オブジェクトの作成に余分な時間がかかります。Javaでのメモリ割り当ては、malloc/callocなどよりも5倍から10倍高速です。得られた時間は、テーブル内のオブジェクトに注意するなどの手順ですべて失われます。私は一度試しました。ループ内に 100000 個のオブジェクトを作成し、2 つのケースでプログラムが終了するまでの時間を測定します。20% 高速であることがわかりました。
(2b) から: メモリ リークと飢餓。キュー内のオブジェクトが大量のメモリ リソースへの参照を持っている場合、このオブジェクトが GC の準備ができていない限り、それらのオブジェクトはすべて解放されません。すべてのオブジェクトが重いオブジェクトである場合は、不足する可能性があります。
(2b) より: finalize() は 1 回だけ呼び出されるため、finalize() で「この」オブジェクトへの強い参照があった場合はどうなるでしょうか。次にオブジェクトの finalie() が呼び出されないため、オブジェクトが一貫性のない状態のままになる可能性があります。
finalize() 内で例外がスローされた場合、それは無視されます。
GC がいつ呼び出されるかを制御できないため、 finalize() がいつ呼び出されるかはわかりません。finalize() の値を出力しているのに、finalize() が呼び出されるまでにプログラムが終了している可能性があるため、出力が表示されないことがあります。
したがって、使用は避けてください。代わりに、dispose() というメソッドを作成して、必要なリソースを閉じるか、最終的なログなど のために完全な投稿を行います。これがクリアされることを願っています。