1

だから私は2000のようなオブジェクトを作成するアプリケーションを持っています。

オブジェクトごとに、Webページ(約75kbの文字列)をダウンロードし、htmlツリー全体のDOMドキュメントオブジェクトモデルを作成し、文字列を破棄します(範囲外になります)。

次に、DOMからいくつかのテキストとリンクを抽出し、DOMを破棄します(nullに設定することにより)。

約1000個のオブジェクトの後(開いているアプリケーションの量によっては、50個のオブジェクトの後になる場合があります)、OutOfMemory例外が発生し、Process Explorerを使用すると、メモリフットプリントが対数ステップで全体的に増加していることがわかります。

nullに設定してから挿入してみましSystem.gc();たが、メモリ使用量は増え続けていますが、対数ステップではなく、処理されたオブジェクトごとに約0.5Mbのステップがあります。さらに、デバッグ中はSystem.gc()、フットプリントをステップオーバーするたびにこの量だけ増加し、命令ポインターがSystem.gc()再び同じになるまで同じままになります。

[編集]

回答で提案されているように、ダンプでプロファイルを実行したところ、これらのクラスのすべてに150kbの文字列(75k文字)がまだ格納されていることがわかりました。これは合計242mbです。したがって、問題は、元の文字列を保持せずにサブ文字列を保持するにはどうすればよいかということです。どうやらStringコンストラクターがこれを行っているようです。

4

4 に答える 4

2

これはメモリリークのようです。HTML(?)を解析した後、HTTP接続を閉じたり、クリーンアップしたりしていないと思いますが、それは推測にすぎません。問題を診断するには、次の2つのオプションがあります。

  • メモリ不足エラー()にメモリをダンプし、-XX:+HeapDumpOnOutOfMemoryErrorメモリプロファイラを使用します。何がメモリの大部分を占めるかを教えてくれます

  • いくつかの処理ステップ(HTTPを介したデータのフェッチ、HTMLの解析、データの抽出)を削除して、どのステップがないとメモリの増加が停止するかを確認してください。この手順により、メモリリークが発生します。

また、電話をかけSystem.gc()ても役に立ちません。

于 2012-05-13T16:43:13.177 に答える
1

まず最初に、JVMにガベージコレクションを強制することはできません。提案APIのみを作成できます。さらに何かをに設定してnullも、オブジェクトへのすべての参照が削除されたことを保証するものではありません。私の推測では、あなたは文字列プールについて忘れていると思います。 コードを見ずに、これらは私たちが作業しなければならない仮定です。また、JVM内の時間とリソースの膨大な浪費であるため、結果を毎回破棄するのではなく、キャッシュすることを検討する必要があります。

于 2012-05-13T16:42:03.320 に答える
1

サブストリングを抽出するときの問題の1つは、長い元の文字列がまだ参照されていることです(1つのオリジナルから多くのサブストリングを作成する場合は良いですが、オリジナルが非常に長く、単一のサブストリングのみを使用する場合は悪いです)。

メモリのダンプを作成して、保持されているオブジェクトとそれらが参照されている場所を確認してください。ダンプは、メモリがいっぱいのときに-XX:HeapDumpOnOutOfMemoryErrorを使用して取得できます。jmap -dump:format = b、file=heap.binを使用してダンプを取得することもできます。これにより、ドキュメントを処理するたびにダンプを取得し、Eclipse Memory Analyzer Tool(MAT)を使用してダンプを比較して、作成および保持された新しいオブジェクトを確認できます。

于 2012-05-14T06:53:59.260 に答える
0

診断目的を除いて、ガベージコレクタを明示的に呼び出す正当な理由はめったにありません。

DOMから文字列を抽出するときは、プログラムの別の部分がDOMから直接取得したものへの参照を保持している場合は、必ずそれらをintern()するか、独自のオブジェクトプーリングを実装してください。

プロファイラーを使用して、破棄していると思われるDOMまたはその他のオブジェクトへの参照を保持しているものが他にないことを確認します。また、Javaの組み込みDOM実装には約5倍のメモリオーバーヘッドがあり、最大ヒープサイズ(-Xmx)が十分に大きいことを確認してください。

于 2012-05-14T07:38:44.823 に答える