15

〜300のJUnitテストを実行し、Springコンテキストを使用しているときに、「java.lang.OutOfMemoryError:PermGenspace」が表示されます。それ以来、PermGenを食いつぶしているものを理解するのに苦労しています:

  • 定常状態では、アプリは約90mのpermgenスペースを消費します
  • 私はユニットテストのために-XX:MaxPermSize=256mを試しました-まだ不足しています
  • 有効にする-XX:+TraceClassLoading-XX:+TraceClassUnloading、の前の最後の20〜30のテストを実行しているときに、追加の「読み込み」イベントが表示されませんOutOfMemoryError

後者は、Classオブジェクト以外の何かがPermGenを埋めていることを示唆しているようです。もしそうなら、それは何でしょうか?たとえば、クラスインスタンスがPermGenに保存される状況はありますか?

これが私のVM情報です:

$ java -version
java version "1.6.0_25"
Java(TM) SE Runtime Environment (build 1.6.0_25-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode)

関連している

FWIW、この投稿を引き起こした私の問題の根本はやや些細なことであることが判明しました:Maven SurefireプラグインがVMをフォークするときにMAVEN_OPTS(またはmvnを実行するVMインスタンス)からVM設定を継承すると仮定しました-それは(ブーイング)しません。プラグインの構成でargLineを使用して明示的に指定する必要があります。HTH。

4

3 に答える 3

4

インターンされたStringインスタンスはPermGenに格納されるため、 String.intern()を乱用すると、 PermGenスペースエラーが発生する場合があります。

これはあなたが見ているものかもしれません-これが問題を解決するかどうかを確認するために不要なString.intern()呼び出しを削除してみてください。一般に、次の両方が当てはまることが確実でない限り、String.intern()の使用はお勧めしません。

  • 限られた数の文字列のみが追加されることを確認してください
  • 同じオブジェクトIDを共有するには、実際にはそのような文字列が必要です(たとえば、同じ文字列の多くのインスタンスが許容できない量のメモリを消費する場合、または複雑なパフォーマンス上の理由で文字列の比較に==を使用する必要がある場合)
于 2011-06-14T17:37:23.960 に答える
2

数百メガバイトの文字列が表示される可能性は低いですが、インターン文字列もpermgenに格納されます。プロキシを使用している各SpringBeanは、実行時にその場で新しいクラスを生成して、プロキシしているインターフェイスを実装していることを忘れないでください。(または、CGLIBプロキシなどを使用している場合はクラス)したがって、JUnitごとに「新しい」Spring ApplicationContextを作成している場合、実際にはすべてのプロキシなどの300個のコピーをクランクアウトしています。

また、Classのインスタンスは、permgenスペース全体ではなく、クラスローダーごとに一意であるため、実行の設定方法によっては実際に重複する可能性があることを忘れないでください(コンテナーなどでのデプロイが含まれる場合、それはJUnit :))。

于 2011-06-14T17:40:33.337 に答える
1

64ビットJVMを実行していることに気付きました。これらは、割り当てごとに2倍のメモリスペースを必要とするため、マシン上の実際のメモリの2倍を使用することが知られています。

Springコンテキストを実際にロードするJUnitテストがある場合(結局のところUnitではありません)、これらはappContext内のすべてのBeanをインスタンス化します。これには、128MB(64ビットボックスでは256MB)を超えるメモリが必要になる可能性があります。

私の経験では、64ビットマシンの大規模なテストスイートに0.5ギガ以上を割り当てるのは馬鹿げたことではありません。512mbまたは1gbに上げてみてください。

これらは、私がより大きなプロジェクトのテストスイートの1つを実行するオプションです...

-Xms256m
-Xmx512m
-XX:MaxPermSize=512m
于 2011-06-14T17:44:00.043 に答える