プログラムでヒープダンプを実行しました。メモリ アナライザー ツールで開いたところ、java.lang.ref.Finalizer
fororg.logicalcobwebs.proxool.ProxyStatement
が大量のメモリを占有していることがわかりました。これはなぜですか?
2 に答える
メソッドを実装するクラスもありますObject.finalize()
。このメソッドをオーバーライドするオブジェクトは、バックグラウンド スレッド コール ファイナライザーによって呼び出される必要があり、これが発生するまでクリーンアップできません。これらのタスクが短く、これらの多くを破棄しない場合、すべてうまく機能します。ただし、これらのオブジェクトを大量に作成したり、ファイナライザーに時間がかかる場合は、ファイナライズするオブジェクトのキューが増えます。このキューがすべてのメモリを使い果たす可能性があります。
解決策は
- 可能であれば finalize() されたオブジェクトを使用しないでください (オブジェクトのクラスを作成している場合)
- ファイナライズを非常に短くします(使用する必要がある場合)
- そのようなオブジェクトを毎回破棄しないでください (それらを再利用してみてください)
既存のライブラリを使用しているため、最後のオプションが最適です。
私の知る限り、Proxool は JDBC 接続用の接続プールです。これは、アプリケーションが接続プールを誤用していることが問題であることを示唆しています。ステートメント オブジェクトを呼び出す代わりにclose
、コードはおそらくそれらおよび/またはその親接続をドロップしています。Proxool はファイナライザーに依存して、基礎となるドライバーによって実装されたオブジェクトを閉じています ... しかし、これにはそれらの Finalizer インスタンスが必要です。また、接続が必要以上に頻繁に (実際の) データベース接続を開いたり閉じたりしていることを意味し、パフォーマンスが低下する可能性があります。
finally
したがって、リークされた ResultSet、Statement、および/または Connection オブジェクトのコードをチェックし、それらをブロックで閉じることを確認することをお勧めします。
メモリ ダンプを見て、898,527,228 バイトがどこに行くのか心配していると思います。大多数は、ID が である Finalizer オブジェクトによって保持されます2aab07855e38
。まだダンプ ファイルがある場合は、それが何を Finalizer
指しているのかを調べてください。Proxool オブジェクトよりも問題があるように見えます。