Javaファイナライズに関するいくつかの質問があります。 たとえば、FileHelperクラスが1つあり、このクラスはファイルの読み取り、ファイルの書き込みなどに関連しています。 私はfinalize()メソッドをオーバーライドしてファイルを閉じるか、writeFile()メソッドの内部でファイルを閉じることができるかどうかをFileHelper class.NowのファイルwriteFile()で確認します。 自体?それは正しい方法ですか? File変数をメンバ変数として宣言しました。オーバーライドが悪い考えである場合、なぜfinalize()メソッドをオーバーライドしたいのですか?どのシナリオですか?私はファイルやフォントなどのシステムリソースを閉じることを言っている多くの記事を読んでいます。Javaファイナライズに関する疑問
答えて
可能な限り早くファイルを閉じることをお勧めします。あなたはFileHelperの静的メソッドを持っている場合は(あなたのヘルパーは、静的な「ヘルパー」メソッドの集まりであると仮定して)私が最優先のファイナライズの目的は、例えば、アンマネージリソースを解放している
static void writeFile(String fileName, String text) { // Exception
// Open file here
// write text
// close it
}
内のファイルを閉じます誰かがそれを忘れた場合のためのファイル。 GCは、ファイルを実行したときの内側()誰かがあなたのヘルパーこのよう
FileHelper fileHelper = new FileHelper(file);
fileHelper.writeFile(text);
// forgot to fileHelper.close();
を使用して、ファイナライズを上書きし、Closeを呼び出している場合は閉じられます。問題:
- 私は、以前のファイルはできるだけ早く閉じる必要があります言及したよう(ただし、早く;))GCが開始されますとき
- それは決定不能だが(何体も知らない)
- にのみ使用する必要があります呼び出し元がファイルを閉じるのを忘れる場合を避けるために。
finalize()を上書きするのは良い方法ではありません。私はコードでそれをやっただろう。
ファイナライザの使用はほとんどすべての状況で悪い考えです。 Java仕様によれば、ファイナライザが実行されることは保証されていません。たとえそれがあったとしても、いつ起こるかはあなたがコントロールできません。
ファイルを閉じるためのプライマリメカニズムとしてファイナライザを使用することは、常に悪い考えです。どうして? GCが長時間実行されないと、アプリケーションでファイル記述子が使い果たされ、ファイルオープンが失敗します。
開かれたストリームを処理する最も良い方法は、ローカル変数とパラメータにそれらを保持し、終了時に常に閉じていることを確認することです。try { ...} finally
を使用します。またはJava 7では、新しい「リソースを試してください」構文を使用します。
ストリームをメンバー変数に入れる必要がある場合は、ストリームを閉じるメソッドを親クラスに実装し、親クラスのインスタンスが閉じられることを確認する必要があります。
また、ストリーム「失われた」閉じるために、ファイナライザを使用して少しポイントがあることに留意すべきです。 が必要な外部リソースを使用するストリームクラスは、これを閉じるためのファイナライザを既に持っています。閉じるにはが必要です。
finalize()メソッドは、Javaガベージコレクタがオブジェクトを再利用しようとしているときにのみ呼び出されます。 finalizeメソッドでファイルハンドルを解放するのは悪い習慣です。
java.io.IOExceptionが発生する可能性があります。開いているファイルが多すぎると、ガベージコレクタがいつ実行されるかを保証できません。
もっと良いオプションは、finallyブロック内のファイルリーダー/ライターオブジェクトを閉じることです。実行が保証されているので。
finally {
// Always close input and output streams. Doing this closes
// the channels associated with them as well.
try {
if (fin != null)
fin.close();
if (fout != null)
fout.close();
} catch (IOException e) {
}}
フィンとfoutはFileInputStreamオブジェクトとFileOutputStreamオブジェクトです。
- 1. ユニークな日付の問題に関するJavaの疑問
- 2. yieldに関する疑問()
- 3. グリッドシステムに関する疑問
- 4. Jpcapcaptureに関する疑問
- 5. CodeIgniter:HMVCとViewsに関する疑問
- 6. レンダリングに関するSDLの疑問
- 7. C++ポインタに関する疑問
- 8. オンプレミス・アクティブ・ディレクトリに関する疑問
- 9. アンドロイドアプリ開発に関する疑問
- 10. Bazelでconfig_settingに関する疑問
- 11. Java再帰ルーチン疑問
- 12. Javaでのガベージコレクションの疑問
- 13. が疑問に思うのJava
- 14. MongoDBに関する疑問を明確にする
- 15. Javaで1つ以上の疑問符
- 16. SqliteのファイナライズとDbロックの問題
- 17. Apache Camel - JDBCストアドプロシージャとトランザクション処理に関する疑問
- 18. 利用可能なリソースと価格に関する疑問
- 19. iosアプリケーションでのメモリ管理に関する疑問?
- 20. WinsockカーネルバッファとNagleアルゴリズムに関する疑問
- 21. C#/ Asp.Net 3.5アプリケーション自動ビルダーサーバーの設定に関する疑問
- 22. 抽象クラスの子クラスのインスタンス化に関する疑問
- 23. Laravel 5画像/ファイルアップロードに関する疑問
- 24. Sparkのリソース使用に関する疑問
- 25. gcc O3最適化フラグに関する疑問
- 26. アプリケーションの構造と通信の方向に関する疑問
- 27. Composerのrequireとrequire-devに関する疑問
- 28. GCDとスレッドクラスの違いに関する疑問
- 29. SQLiteOpenHelperに関する疑問と複数のテーブルの作成
- 30. Visual Studio 2010のセットアッププロジェクトに関する疑問
finalizeをオーバーライドすると、色の注釈を追加すると、GCがさらに高価になり(オブジェクトは少なくとも2回のGCパスを経て生き延びる)、JVMはメソッドを任意のタイムリーな方法で呼び出す義務はない - または全く。ファイナライズとGCについてはさまざまな記事がありますが、その方法をオーバーライドすることを強くお勧めします。 – yshavit
もちろん、これはコーナーケースです。 I/Oを行うとGCのオーバーヘッドが心配されることはありません。私のローラーブレードとジェットを比較してみました。 –
間違いなく、OPがnon-IOクラスでこのメソッドを使用することを検討していた場合には、私は精緻化していました。私が主題にいる間、私はそれを言いたいと思った。 – yshavit