-1

そこで、テストでメモリ リークの可能性を自動的に検出して指摘できるコードを書くというアイデアを思いつきました。実装に苦労する前に、自分のアイデアが妥当かどうかを確認したかっただけです。

基本的に、メモリ リークは、未使用の参照がますます増加することとして定義されます。Java では、C++ と比較して、この危険性が大幅に軽減されます。これは、ポインターをぶら下げたり、delete() を忘れたりする危険性がないためです。

したがって、これにより、Java でメモリ リークが発生する可能性が制限されます。オブジェクトへの静的参照を持つことも、現在実行中のスレッドでローカル参照を持つこともできます。

私の考えは、すべての既知のプロジェクト クラス ファイルを調べて、すべての静的参照を引き出すルーチンを作成することです。次に、参照を「再帰」する必要があり、それが持つすべてのインスタンス参照をカウントアップする必要があります。オブジェクト参照はある程度のメモリを必要とし、プリミティブはある程度のメモリを必要とし、それらすべてを集計できます。このルーチンを 1 回トリガーしてベースラインを取得し、メモリ リークの原因と思われることを実行してから、ルーチンを再度実行して結果を比較します。デルタしきい値を設定すると、意図的に大きくなったオブジェクトと、大きくなるべきではないオブジェクトを手動で判断できます。

もちろん、これはテスト ツールですが、私が取り組んでいるプロジェクトでは、これらのエラーを多くのユーザーがいる本番環境でしか再現できないことが多いため、実際のプロファイラーを使用することが常に選択肢になるとは限りません。これを組み込むことで、プロファイラーを実際に実行する必要がなくなり、製品の問題を診断する場合を除いて、ほとんどの場合、通常の操作が可能になります。

私が見る唯一の問題は、現在実行中のスレッドのローカル変数にこの方法でアクセスできないことですが、その制限を知っていると、これらのローカル (ただし長期参照) をテストクラス自体に登録するコードが必要になる可能性があります。これらのオブジェクトへの弱い参照を静的変数に保持することで、参照をカウントできるようにします。

ガベージ コレクションが問題になるため、基本的には参照されていないオブジェクトを作成することでガベージ コレクションを「強制」し、収集時にスレッドに通知するために finalize をオーバーライドします。これにより、GC 検出器のブロックが停止し、漏れ検出器。

それで、私の質問は、これはもっともらしく聞こえますか? これは有用な結果をもたらすと思いますか?

4

2 に答える 2

2

したがって、これにより、Java でメモリ リークが発生する可能性が制限されます。オブジェクトへの静的参照を持つことも、現在実行中のスレッドでローカル参照を持つこともできます。

いいえ 。別の原因の網羅的でないリストについては、Java でメモリ リークを作成するを参照してください。これらの原因のほとんどは、あなたのアプローチでは検出されません。

私が取り組んでいるプロジェクトでは、多くの場合、多くのユーザーがいる本番環境でしかこれらのエラーを再現できないため、実際のプロファイラーを使用することが常に選択肢とは限りません。これを組み込むことで、プロファイラーを実際に実行する必要がなくなり、本番製品の問題を診断する場合を除いて、ほとんどの場合、通常の操作が可能になります。

本番システムにいつでもヒープ ダンプを書き込むことができます (Oracle JVM には、OutOfMemoryError が発生するたびにヒープ ダンプを書き込む設定もあります)。その後、これらのヒープ ダンプを分析できます (そのためのさまざまなツールがあり、ヒューリスティックを適用して "リークの疑い" を自動的に検出するツールもあります)。

于 2012-09-17T17:42:25.303 に答える
1

Java 1.5 以降、クラス ヒストグラムを出力できる jmap があります。

于 2012-09-17T17:39:28.470 に答える