2011-12-30 21 views
3

実際にJavaでfinalize()メソッドを使うべきですか?Javaではfinalize()メソッドをいつ使うべきですか?

我々はファイナライズで接続を(クローズする場合)メソッドは、それはGCが確定()メソッドを呼び出して、接続を解放するのを待って、以下のコードを使用することをお勧めしますだから感覚

try{ 
// Connection creation 
}finally{ 
//close connection 
} 

がありません質問はfinalize()メソッドは今日どんな関連性がありますか?

+3

'finally'と' finalize'は全く異なるものです。 –

+1

あなたの質問に答えるために、いいえ、私は決して約15年間のJava開発でファイナライズメソッドを実装していません。 –

+1

@PaulTomblinええ、あなたがここで表示しようとしているものは、finalize()メソッドで接続を閉じることとは別のものです。それは、私は最終的にブロックで接続を閉じるよりも、GCがfinalize()をコールしてから接続を解放するのを待っています。 finally {}を使用すると、接続が解放されたときに制御できます。希望は私が意味を作っている – Jyotirup

答えて

7

実際にはメソッドを明示的に呼び出してリソースを解放することをお勧めします。ファイナライザは、必ずしも速やかに呼び出されるわけではありません。パフォーマンスペナルティが加わります。

しかし、ファイナライザは、クライアントが明示的に処分するのを忘れてしまった場合に備えて、リソースを解放するためのセーフティネットとしても使用できます。

ジョシュア・ブロックの中で「ファイナライザを避け、」トピックから「有効ジャワ、」第2版:

[D]はセーフティネットとして、あるいは重大でない ネイティブリソースを終了させる以外ファイナライザを使用しon't。まれに、ファイナライザを使用する場合、 はsuper.finalizeを呼び出すことを忘れないでください。ファイナライザをセーフティネットとして使用する場合は、 ファイナライザから無効な使用状況をログに記録することを忘れないでください。

+2

私は通常、すべてのリソースが適切に処分されたことを確認するために、アサーションをfinalizeに入れます(そして、シャットダウン時にファイナライザを実行するようにVMを設定します)。開発中にバグを捕まえるのは良いことですが、実稼働環境では使用すべきではありません。 – Voo

0

finalize()は、socketのようなリソースを解放するだけでなく、メモリを管理します。理論的に言えば、コード内で明示的にfinalize()を呼び出す必要はありません。 VMによって適切な時間に実行されます。

+0

finalize()メソッドをどのような環境でオーバーライドする必要がありますか? – Jyotirup

+0

@Jyotirupこれまで決して 'finalize()'を実装していません。 'finalize()'関数は 'C++'の 'destructor'によく似ています。それを上書きする必要がある場合は、リソースの解放に関連するものがなければなりません。しかし、ほとんどの場合、JVMはそれを正しく完了させるのに役立ちます。すばやいグーグルで私にこのhttp://www.google.com.hk/#hl=zh-CN&newwindow=1&safe=strict&sa=X&ei=2_T9ToWFCMqTiQeT1sntCg&ved=0CBkQvwUoAQ&q=when+to+override+finalize+java&spell=1&bav=on.2 、または.r_gc.r_pw。、cf.osb&fp = a828595b5987e1c0&biw = 1308&bih = 596、私は最初の3つのリンクが役に立つかもしれないと思います。 –

+3

@Summer 'finalize'は、C++のデストラクタに似た絶対的な** NOT **です。デストラクタは決定的です。それがRAIIにとって有益なのです。 Finalizeにはいくつかの問題がありますが、そのほとんどはバグを探す以外には役に立ちません。特にフードの中で起こっていることを理解していない場合(つまり、いつJVMがファイナライザを実行するのか、そしてその結果が何であるか) – Voo

1

短い答えは決してありません。 Finalize()は微妙な問題でいっぱいで、ガーベジコレクションを大幅に遅くします。

もっと長い答えは、開発中に重要な接続、ファイル、ソケットなどが閉じられているかどうかをチェックし、そうでなければ警告を記録して、開発者が調査し、問題。

2

私はfinalize()を使用するために考えることができる唯一のユースケースは、次のとおりです。

はあなたのクラスの静的リソース(メンバー)を持っており、クラスの時にそのリソース上のいくつかのクリーンアップ、ファイナライズや伐採をしたいと仮定アンロードされると、finalize()メソッドをオーバーライドしてそのすべてを行う必要があります。

+1

静的リソースの場合+1。 –

+4

静的リソースがある場合、クラスのインスタンスが収集されるたびにアンロードする必要はありません。シャットダウン時などに静的リソース(十分にすべてのリソース)を解放する必要がある場合は、明示的に行う必要があります。少なくとも、ファイナライズを使用するのとは逆に動作します。 – Voo

+0

あなたのクラスが実際にあなたのアプリケーションの存続期間中に一度だけ(シャットダウン時に)ロードされ、アンロードされる 'singleton'オブジェクトであれば、アプリケーションはまったく存在しないPOJOになりますフレームワークはシャットダウン/破壊のフックを提供しましたか? – anubhava

-1

実質的にfinalize()は、リソースをクリーンアップするために使用すべきではありません。リソースが取得された場合は、パフォーマンスの観点から、JVMがfinalize()を呼び出すのを待つのではなく、リソースを明示的に解放する方がよいでしょう。 JVMがfinalize()を呼び出す時期は予見できません。また、リソースの処理が完了していれば、不必要に長く保持しているリソースもあります。 私は誰かがfinalizeメソッド内で変数を無効にするのを見ました。これは、完全に不要なコード行を使ってGCサイクルを拡張することによってプログラムを遅くするという悪い習慣です。 GCは、非常に致命的なオブジェクトの処理を処理するように設計されています。

関連する問題