0

私のコードは次のようなことをしています:

for(SomeObject so : someObjects)
{
  Blah b = so;
  NewObject n = dao.GetNO(b.23);
}

つまり、各反復で for ループ内に新しい変数を作成しています。

これがメモリ不足の問題の原因でしょうか?

Netbeans によって報告されたエラー:

Caused by: java.lang.OutOfMemoryError: Java heap space
        at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:133)
        at java.lang.StringCoding.decode(StringCoding.java:173)
        at java.lang.String.<init>(String.java:443)
        at java.lang.String.<init>(String.java:515)
        at com.gargoylesoftware.htmlunit.WebResponseImpl.getContentAsString(WebResponseImpl.java:215)
        at com.gargoylesoftware.htmlunit.WebResponseImpl.getContentAsString(WebResponseImpl.java:205)

Upate これは Java コンソール アプリケーションであり、アプリ全体は基本的に in forloop で実行されます。

4

3 に答える 3

5

Java 5 以降、またはレガシー JVM のいずれかで実行していますか? Java コマンド ラインに -XX:+HeapDumpOnOutOfMemory を設定するか、JConsoleを使用してプロセスにアタッチし、ヒープ ダンプを要求することで、OOM の原因を突き止めることができます。その後、Eclipse MATツールを使用してダンプを開き、オブジェクト グラフを表示して、プログラム内のオブジェクトを誰が保持しているかを確認できます。MAT には、オブジェクト グラフを支配するオブジェクトを表示するビューがあります。そのため、正確に何がリークしているのかが非常に明確になります。スタック トレースを調べることは役に立ちません。また、プログラムのある場所でのリークが別の場所での割り当ての失敗を引き起こす可能性があるため、誤解を招く可能性があります。

于 2010-01-06T19:08:41.407 に答える
1

メモリに収まるより多くのオブジェクトを保持しようとすると、メモリが不足します。ループ内でオブジェクトを作成している場合、オブジェクトが範囲外になるとすぐに GarbageCollected が取得されます。

だからあなたが書くなら

for (.....){
   Object o = new Object();
}

- o の複数のインスタンスを保持することは決してないので、それが原因になることはありません (ループ スコープ外のマップに配置するなどして、それらへの参照を別の場所に保存する場合を除きます)。

より多くの参照を保持しているコード内の場所を探す必要があります。あなたの投稿から、それ以上のことはわかりません。

ところで、JVM で使用しているメモリの量を -Xmx および -Xms オプション (詳細については「java -X」と入力) で増やすことを検討することもできます。間違いを見つけるのに役立ちます。netbeans 内で実行しているため、同じ JVM で実行されているため、メモリが不足している可能性もあります。私はネットビーンズを使用していませんが、ネットビーンズが新しいプロセスをフォークしてプログラムを実行できるかどうかを確認して確認できます(小さくないネットビーンズとメモリを共有しながら実行しようとしないようにするため)、または試してくださいコマンドラインで直接実行します。

于 2010-01-06T18:38:19.330 に答える
0

最も可能性が高いのは、どこかのオブジェクトを誤って保持している可能性があります。通常の犯人は、実装が不十分なキャッシュ、または機能的に同等のものです。

もう 1 つの可能性は、何をしていても十分なメモリがないということです。Java は (少なくとも Sun はデフォルトで) 64 MB のヒープで開始します。-xmxこれはパラメーターで変更できます。

最後に、(特定のガベージ コレクターの実装で) ガベージ コレクションに十分な時間 (合計プロセス CPU 時間のパーセンテージとして) が費やされた場合、OutOfMemoryError が発生する可能性があることを 1.4.X 日で思い出しました。カットオフは 90% の範囲でした。私はこれをほぼ 10 年に一度見たことがありますが、それは本当に神経質な使用例でした。おそらくこれではありませんが、そうかもしれません。この動作が最新の Java で持続するかどうかはわかりません。

私のアドバイス: の実装を調べてdao.GetNO(...)、副作用としてオブジェクトが作成されるかどうか、およびそれらの寿命を確認してください。

于 2010-01-06T18:40:47.923 に答える