10

私は自分の質問を説明するために最善を尽くします。ちょっと抽象的かも。

Javaコードで明示的にGCを呼び出さないこと、メソッドをファイナライズすること、nullを指すことなどに関する文献をいくつか読みました。

いくつかの大きな XML ファイル (顧客の請求書) があります。Jaxb を使用して、ファイルは複雑な Java オブジェクトにマーシャリングします。その属性は基本型 (Integer、BigDecimal、String など) ですが、他の複雑なクラスのクラス、他のクラスのリスト、属性としてリストを持つクラスのリストなどもあります。

オブジェクトを操作するときは、メモリから削除する必要があります。一部の XML は非常に大きく、メモリ リークや OutOfMemoryError の状況を回避できます。

だから、私の質問は次のとおりです。

  • 大きなオブジェクトをnullに割り当てるだけで十分ですか? ソフト参照がある場合、GC はオブジェクトを解放しないことを読みました。
  • オブジェクトの詳細なクリア、すべてのリストのクリア、属性への null の割り当てなどを行う必要がありますか?
  • JaxB (私は Java6 を使用しているため、JaxB が組み込まれています) とソフト参照はどうですか? JaxB は古い JibX マーシャラーよりも高速ですが、メモリ使用量が悪いかどうかはわかりません。
  • megacomplex JaxB クラスを WeakReference などでラップする必要がありますか?

Java メモリ使用の概念、JaxB などを混在させてすみません。大規模な実行中のプロセスの安定性を調査しており、.hprof ファイルは、すべての請求書のすべての顧客データがメモリに残っていることを示しています。単純な、基本的な、またはまれな質問でしたらすみません。

前もって感謝します

4

3 に答える 3

9

Big Object (グラフ) の一部を指しているものが他にない限り、Big Object 参照を割り当てるnullだけで十分です。

ただし、最も安全なのは、アプリケーションをしばらく実行した後にプロファイラーを使用し、オブジェクト参照を調べて、適切に GC されていないものがないかどうかを確認することです。

于 2013-06-11T15:07:11.293 に答える
4

大きなオブジェクトをnullに割り当てるだけで十分ですか? ソフト参照がある場合、GC はオブジェクトを解放しないことを読みました。

短い答えはイエスです。大きなオブジェクト (へのすべての強い参照) を null に割り当てるだけで十分です。これを行うと、そのオブジェクトはガベージ コレクターによって "強く到達可能" と見なされなくなります。

OutOfMemoryErrorがスローされる前に、ソフトに到達可能なオブジェクトがガベージコレクションされることが保証されているため、ソフト参照は問題になりません。それらは、ガベージ コレクターがオブジェクトをすぐに収集するのを妨げる可能性があります (そうしないと、弱参照とまったく同じように動作します)。ただし、このメモリ使用は「一時的」であり、割り当て要求を満たすために必要な場合に解放されます。

オブジェクトの詳細なクリア、すべてのリストのクリア、属性への null の割り当てなどを行う必要がありますか?

それはおそらく悪い考えでしょう。フィールド値が外側のビッグ オブジェクトによってのみ参照される場合、ビッグ オブジェクトが収集されるときにそれらもガベージ コレクションの対象になります。そうでない場合、それらを参照するコードの他の部分は、使用しているリストからメンバーを削除していることを認識できません!

最良の場合、これは何もしません。最悪の場合、プログラムが壊れます。この魅力に惑わされて、オブジェクトが強力に到達可能かどうかという唯一の実際の問題に対処することから気をそらされないようにしてください。

JaxB (私は Java6 を使用しているため、JaxB が組み込まれています) とソフト参照はどうですか? JaxB は古い JibX マーシャラーよりも高速ですが、メモリ使用量が悪いかどうかはわかりません。

私は、これらのライブラリの相対的な時間と空間のパフォーマンスに特に精通していません。しかし、一般的には、コア ライブラリに対して非常に強い「有罪が証明されるまで無実」の態度をとることは安全です。メモリ リークのバグがあった場合は、おそらく今までに発見、報告、修正されているはずです (非常にニッチなことをしている場合を除きます)。

メモリ リークが発生した場合、99.9% の確率で自分のコードに問題があると確信しています。

megacomplex JaxB クラスを WeakReference などでラップする必要がありますか?

これは、実際に何が必要かを考えずに、問題に GC の「修正」を投げかけているように思えます。

JaxB クラスを弱く参照する必要がある場合は、これを行うことをお勧めします (既に存在しているはずです)。しかし、そうすべきでない場合は、絶対にこれをしないでください。弱い参照は、全体的なセマンティクスの問題であり、メモリの問題を回避するために特に導入するべきではありません。

外側のコードでオブジェクトへの参照が必要な場合は、参照が必要です。インスタンスをガベージ コレクションしても利用できるようにするためにできる魔法はありません。(特定のポイントを超えて) 参照が必要ない場合は、まったく必要ありません。標準の [強力な] 参照を無効にするか、範囲外にすることをお勧めします。弱参照は特殊な状況であり、通常、オブジェクトが関連しなくなるポイントを完全に制御できない場合に使用されます。ここではおそらくそうではありません。

.hprof ファイルは、すべての請求書のすべての顧客データがメモリに残っていることを示しています。

これは、それらが実際に必要以上に長く参照されていることを示唆しています。

幸いなことに、hprof ファイルには、それらを参照しているものの正確な詳細が含まれます。GC されていると思われる請求書インスタンスを見て、それを参照しているものと GC を妨げているものを確認します。次に、問題のクラスを調べて、その参照が解放されると予想される方法と、この場合に解放されなかった理由を確認します。

すべての優れたパフォーマンス/メモリ調整は、測定に基づいています。ヒープ ダンプを取得し、インスタンスとそれらへの参照を検査することが測定値です。役立つかもしれないという期待で WeakReferences に何かをラップしようとするのではなく、これを実行して結果に基づいて行動してください。

于 2013-06-11T17:16:41.330 に答える