「java.lang.OutOfMemoryError:PermGen space」エラーへの対処


1222

最近、私のWebアプリケーションでこのエラーに遭遇しました:

java.lang.OutOfMemoryError:PermGen space

これは、Tomcat 6およびJDK 1.6で実行される典型的なHibernate / JPA + IceFaces / JSFアプリケーションです。どうやらこれは、アプリケーションを数回再デプロイした後に発生する可能性があります。

何が原因で、それを避けるために何ができますか?どうすれば問題を解決できますか?


私はこれを何時間も戦いましたが、良いニュースはありません。私の関連する質問を参照してください:stackoverflow.com/questions/1996088/…メモリリークが発生している可能性があります。たとえば、WebAppClassLoaderがガベージコレクションされていないため、クラスはガベージコレクションされていません(外部参照がクリアされていない)。PermGenを増やすとOutOfMemoryErrorが遅延するだけであり、クラスのガベージコレクションを許可することが前提条件ですが、クラスローダーがクラスへの参照をまだ持っている場合は、クラスのガベージコレクションを行いません。
エランメダン2010年

display taglibを追加するときにこのエラーが発生しました。削除すると、エラーも解決しました。なんでそうなの?
マスト

そして、どうやってそれに遭遇しましたか?
するThorbjörnRavnアンデルセン

13
JDK 1.8を使用します
。þMetaSpace

Windowsを使用している場合は、設定ファイルでフラグを手動で設定する代わりに、次の手順に従ってください。これにより、実行時にTomcatによって呼び出されるレジストリの値が適切に設定されます。 stackoverflow.com/questions/21104340/...
冒険野郎マクガイバー

回答:


563

解決策は、Tomcatの起動時にこれらのフラグをJVMコマンドラインに追加することでした。

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

これを行うには、tomcatサービスをシャットダウンしてから、Tomcat / binディレクトリに移動してtomcat6w.exeを実行します。[Java]タブで、[Javaオプション]ボックスに引数を追加します。「OK」をクリックして、サービスを再起動します。

エラーが発生し場合、指定されたサービスはインストールされたサービスとして存在しないため、実行する必要があります。

tomcat6w //ES//servicename

ここで、servicenameはservices.mscに表示されるサーバーの名前です。

出典:上ORXさんのコメントエリックのアジャイル回答


39
以下の記事では、-XX:+ UseConcMarkSweepGCおよび-XX:MaxPermSize = 128mも推奨し​​ています。 my.opera.com/karmazilla/blog/2007/03/13/…–
テイラーリース、

30
-XX:+ CMSPermGenSweepingEnabledこのオプションは、パフォーマンスを低下させます。これにより、我々のシステムでは、各リクエストに通常より3倍の時間がかかります。注意して使用してください。
Eldelshell

10
私のために働いた-ありがとう-私はこれをUbuntu 10.10のTomcat6でやっています-私は新しいファイル/usr/share/tomcat6/bin/setenv.shを作成し、それに次の行を追加しました:JAVA_OPTS = "-Xms256m -Xmx512m- XX:+ CMSClassUnloadingEnabled -XX:+ CMSPermGenSweepingEnabled "-sudo /etc/init.d/tomcat6 start
sami

24
Tomcat 6.0.29の起動時、私のcatalina.outログファイルから:「今後はCMSPermGenSweepingEnabledの代わりにCMSClassUnloadingEnabledを使用してください」
knb

222
まず最初に、これらのフラグが実際に何をするかを説明するのは素晴らしいことです。ただ言う:「それをして楽しんでください」だけでは十分ではありません。
Nikem

251

あなたはより良い試す-XX:MaxPermSize=128Mのではなく-XX:MaxPermGen=128M

このメモリプールの正確な使用法はわかりませんが、JVMにロードされたクラスの数に関係しています。(したがって、tomcatのクラスのアンロードを有効にすると、問題を解決できます。)アプリケーションが実行時にクラスを生成およびコンパイルする場合、デフォルトより大きなメモリプールが必要になる可能性が高くなります。


9
実際には、これはOOMErrorのみを延期します。anonによって開始された以下の回答を参照してください。
Rade_303

これらのオプションは、ここで説明されていますoracle.com/technetwork/java/javase/tech/...を
アモス

153

複数のデプロイ後に発生するアプリサーバーのPermGenエラーは、コンテナが古いアプリのクラスローダーに保持している参照が原因である可能性が高いです。たとえば、カスタムログレベルクラスを使用すると、アプリサーバーのクラスローダーによって参照が保持されます。これらのクラスローダー間リークを検出するには、jmapやjhatなどの最新の(JDK6 +)JVM分析ツールを使用して、アプリで引き続き保持されているクラスを調べ、その使用を再設計または排除します。通常の容疑者は、データベース、ロガー、およびその他の基本フレームワークレベルのライブラリです。

Classloaderリーク:恐ろしい "java.lang.OutOfMemoryError:PermGen space"例外、特にそのフォローアップの投稿を参照してください。


3
これは問題の真の解決策にすぎず、場合によっては実装が困難です。
Rade_303

もう1つの非常に優れたソースは、people.apache.org /〜markt / presentations /…です(Tomcatリリースマネージャーから)。
ジヴェンコア

22
これは理論的には質問に答える可能性がありますが、答えの本質的な部分をここに含め、参照用のリンクを提供することが望ましいでしょう
Joachim Sauer

68

人々が犯す一般的な間違いは、ヒープ領域とpermgen領域が同じであると考えることですが、これはまったく正しくありません。ヒープに多くのスペースが残っている可能性がありますが、permgenでメモリが不足する可能性があります。

PermGenのOutofMemoryの一般的な原因はClassLoaderです。クラスがJVMにロードされると、そのすべてのメタデータはClassloaderとともにPermGen領域に保持され、それらをロードしたClassloaderがガベージコレクションの準備ができるとガベージコレクションされます。場合、クラスローダーはメモリリークを起こし、それによって読み込まれたすべてのクラスがメモリに残り、数回繰り返すとpermGenのメモリ不足を引き起こします。古典的な例は、TomcatのJava.lang.OutOfMemoryError:PermGen Spaceです。

これを解決するには、次の2つの方法があり
ます。1.メモリリークの原因を見つけるか、メモリリークがあるかどうかを確認します。
2. JVMパラメータ-XX:MaxPermSizeとを使用して、PermGenスペースのサイズを増やします-XX:PermSize

詳細については、Java のJava.lang.OutOfMemoryErrorの2 Solutionを確認することもできます。


3
パラメータを渡す方法は-XX:MaxPermSize and -XX:PermSize?見つかりませんcatalina.bat。私のTomcatバージョンは5.5.26です。
Deckard 2012年

クラスローダーのメモリリークを見つける方法は?あなたは何かツールをお勧めしますか?
2014

ツールの推奨事項については、@ amitをご覧ください。この質問については、コミュニティーWikiの回答を参照してください。
バレット

@DeckardはTomcat / binディレクトリに移動し、tomcat6w.exeを実行します。「Java」タブで、「Javaオプション」ボックスに引数を追加します。「OK」をクリック
Zeb

43

-XX:MaxPermSize=128mSun JVM のコマンドラインパラメータを使用します(明らかに、必要なサイズを128に置き換えます)。


9
唯一の問題は、避けられないことを遅らせているということです。ある時点で、ヘッドルームも不足します。これは優れた実用的なソリューションですが、完全には解決されません。
ティムハウランド

同じことがEclipseでも発生し、多くの動的クラスロードがある場合はいつでも発生します。クラスローダーは廃棄されず、永遠に永続的な世代に住んでいます
Matt

1
特に大きなHudsonジョブを実行すると、PermGenが足りなくなりました...これで問題が解決しました。
HDave、2011年

10
@TimHowland、根本的な原因がクラスローダーのリークではなく、Webアプリ内のクラス/静的データが多すぎる場合は、永続的な修正となる可能性があります。
ペーテルTörök

ソースからjenkins / hudsonをビルドするときにHDaveと同じ問題が発生しました。
ルイスガブ2014

38

試してみ-XX:MaxPermSize=256mて、それが続く場合は試してください-XX:MaxPermSize=512m


56
それでも解決しない場合は、試してみてくださいXX:MaxPermSize=1024m:)
igo 2013

38
そしてそれはまだ続く場合は、XXを試してみてください:MaxPermSizeを= 2048メートル:)
トーマス・

16
それでもそれが続く場合は、アプリケーションを再考してください!! または、XX:MaxPermSize = 4096m :)を試してください
Jonathan Airey

17
8192mを試すこともできますが、少々やり過ぎです
Jacek Pietal 14年

12
確かにやり過ぎです-だれでも640KBで十分です!
Joel Purra 2015年

28

私はeclipse ideを使用しているため、VM引数追加しました -XX: MaxPermSize = 128m(どれが最適に機能するか試すことができます)。ほとんどのJVMでは、デフォルトのPermSizeは約64MBであり、プロジェクト内のクラスが多すぎたり、文字列の数が多すぎたりすると、メモリが不足します。

日食については、回答にも記載されています

ステップ1:[ サーバー]タブでtomcatサーバーをダブルクリックします

ここに画像の説明を入力してください

ステップ2Launch Conf開き-XX: MaxPermSize = 128m、既存のVM引数の最後に追加します

ここに画像の説明を入力してください


1
詳しい回答ありがとうございます(注:[設定を編集]ウィンドウを開くには、[起動設定を開く]をクリックしてください...しかし、次のパラメーターを使用しました: "-XX:+ CMSClassUnloadingEnabled -XX:+ CMSPermGenSweepingEnabled"
Chris Sim

23

複雑なWebアプリケーションのデプロイとアンデプロイの際にも、この問題に頭を悩ませており、説明と解決策を追加したいと思いました。

Apache Tomcatにアプリケーションをデプロイすると、そのアプリケーション用に新しいClassLoaderが作成されます。次に、ClassLoaderを使用して、アプリケーションのすべてのクラスをロードし、アンデプロイ時に、すべてがうまく機能するはずです。ただし、実際にはそれほど単純ではありません。

Webアプリケーションの存続期間中に作成された1つ以上のクラスは、静的な参照を保持します。これは、行のどこかでClassLoaderを参照します。参照はもともと静的であるため、ガベージコレクションによってこの参照がクリーンアップされることはありません。ClassLoaderとそれがロードするすべてのクラスはそのまま残ります。

そして、いくつかの再デプロイの後、OutOfMemoryErrorが発生します。

現在、これはかなり深刻な問題になっています。再デプロイのたびにTomcatを確実に再起動することはできますが、再デプロイされているアプリケーションだけでなく、サーバー全体がダウンします。これは、多くの場合実行不可能です。

代わりに、Apache Tomcat 6.0で機能するソリューションをコードにまとめました。私は他のアプリケーションサーバーでテストしていません。これは他のアプリケーションサーバーで変更しないと機能しない可能性が非常に高いことを強調する必要があります

また、個人的にはこのコードが嫌いであり、既存のコードを変更して適切なシャットダウンとクリーンアップの方法を使用できる場合は、誰もこれを「クイックフィックス」として使用ないでください。これを使用する必要があるのは、独自の静的参照をクリーンアップする手段を提供しない、コードが依存している外部ライブラリ(私の場合はRADIUSクライアント)がある場合のみです。

とにかく、コードを続けます。これは、サーブレットのdestroyメソッドや(より良いアプローチ)ServletContextListenerのcontextDestroyedメソッドなど、アプリケーションがアンデプロイされる時点で呼び出す必要があります。

//Get a list of all classes loaded by the current webapp classloader
WebappClassLoader classLoader = (WebappClassLoader) getClass().getClassLoader();
Field classLoaderClassesField = null;
Class clazz = WebappClassLoader.class;
while (classLoaderClassesField == null && clazz != null) {
    try {
        classLoaderClassesField = clazz.getDeclaredField("classes");
    } catch (Exception exception) {
        //do nothing
    }
    clazz = clazz.getSuperclass();
}
classLoaderClassesField.setAccessible(true);

List classes = new ArrayList((Vector)classLoaderClassesField.get(classLoader));

for (Object o : classes) {
    Class c = (Class)o;
    //Make sure you identify only the packages that are holding references to the classloader.
    //Allowing this code to clear all static references will result in all sorts
    //of horrible things (like java segfaulting).
    if (c.getName().startsWith("com.whatever")) {
        //Kill any static references within all these classes.
        for (Field f : c.getDeclaredFields()) {
            if (Modifier.isStatic(f.getModifiers())
                    && !Modifier.isFinal(f.getModifiers())
                    && !f.getType().isPrimitive()) {
                try {
                    f.setAccessible(true);
                    f.set(null, null);
                } catch (Exception exception) {
                    //Log the exception
                }
            }
        }
    }
}

classes.clear();

これを書いてから8年以上経過していることはわかっていますが、その間のどこかで、根本的な原因と解決策をより深く見つけました。これは、webapp内のすべてのクラスがコンテキストクラスローダーによって所有されている一方で、起動およびシャットダウンコールバックを呼び出すスレッドが親クラスローダーによって所有されていることです。つまり、シャットダウンコードがスレッドローカル変数を初期化すると、親クラスローダーがコンテキストクラスローダーへの参照を保持してしまい、適切なクリーンアップができなくなります。
エドワードトルベット

幸い、非常に単純な修正があります。現在シャットダウンメソッドにあるすべてのコードを新しいスレッドオブジェクトの実行メソッドに移動します。次に、shutdownメソッドでこのスレッドを開始し、完了するまで待機します。クリーンアップコードは同じように実行されますが、スレッドローカル変数はリークせずにコンテキストクラスローダーにバインドされたままになります。
Edward Torbett

20

java.lang.OutOfMemoryError: PermGenスペースのメッセージは、メモリ内のPermanent世代の面積が排出されることを示しています。

Javaアプリケーションは、限られた量のメモリを使用できます。特定のアプリケーションが使用できるメモリの正確な量は、アプリケーションの起動時に指定されます。

Javaメモリは、次の図に示すように、さまざまな領域に分かれています。

ここに画像の説明を入力してください

メタスペース:新しいメモリ空間が生まれる

JDK 8 HotSpot JVMは、クラスメタデータの表現にネイティブメモリを使用しており、Metaspaceと呼ばれています。Oracle JRockitおよびIBM JVMに似ています。

朗報ですが、これはjava.lang.OutOfMemoryError: PermGenスペースの問題がなくなり、Java_8_Download以降を使用してこのメ​​モリスペースを調整および監視する必要がなくなるということです。


17

1)PermGenのメモリサイズの増加

最初にできることは、永続的な世代のヒープ領域のサイズを大きくすることです。これは、通常の–Xms(set heap size)および–Xmx(set maximum heap size)JVM引数では実行できません。前述のように、永続的な世代のヒープスペースは通常のJavaヒープスペースから完全に分離されており、これらの引数が設定されています。この通常のJavaヒープスペースのスペース。ただし、永続的な生成ヒープのサイズを大きくするために使用できる同様の引数があります(少なくともSun / OpenJDK jvmsを使用)。

 -XX:MaxPermSize=128m

デフォルトは64mです。

2)スイープを有効にする

これを適切に処理する別の方法は、PermGenが不足しないようにクラスをアンロードできるようにすることです。

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

そのようなものは過去に私にとって魔法のように働きました。ただし、permgenスイープは、実行するすべてのリクエストまたはそれらのラインに沿った何かに対して追加の2リクエストのようになるため、これらの使用には大きなパフォーマンストレードオフがあります。使用とトレードオフのバランスをとる必要があります。

このエラーの詳細を見つけることができます。

http://faisalbhagat.blogspot.com/2014/09/java-outofmemoryerror-permgen.html


@faisalbhagatの素晴らしい
10/17

オプション2はすばらしいですが、実稼働環境では使用しないでください。通常は、開発環境のみに保持することをお勧めします。ただし、PermGen
hdost


14

私がここで話している問題がありました、私のシナリオはeclipse-helios + tomcat + jsfで、あなたがやっていたことは単純なアプリケーションをtomcatにデプロイすることです。ここで同じ問題を示していましたが、次のように解決しました。

Eclipseで[ サーバー ]タブに移動し、登録済みのサーバーをダブルクリックします(私の場合はtomcat 7.0)。ファイルサーバーの一般的な登録情報が開きます。「一般情報」セクションで起動構成を開く」リンクをクリックすると、これらの2つのエントリの最後に追加されたVM引数の「引数」タブでサーバーオプションの実行が開きます。

-XX: MaxPermSize = 512m
-XX: PermSize = 512m

そして準備ができています。


14

最近の最も簡単な答えは、Java 8を使用することです。

PermGenスペース専用のメモリは予約されなくなり、PermGenメモリは通常のメモリプールと混ざることができます。

-XXPermGen...=...Java 8が何もしないと文句を言わないようにするには、非標準のJVM起動パラメーターをすべて削除する必要があることに注意してください。


こんにちは、この回答は既に提供されています:stackoverflow.com/a/22897121/505893。明確にするために、回答を削除してください。必要に応じて、私が述べた答えを改善できます。ありがとう;)
2014

6
@bluish指摘していただきありがとうございます。ただし、その答えはOutOfMemoryExceptionsとメタデータのリークについて話しているすべての側に行きます。また、PermGenオプションを削除する際の非常に重要なポイントについても触れていません。要するに、私は答えを改善するかどうかはわかりませんが、むしろそれを書き直します。クイックタッチアップだけなら、私は躊躇することは少ないと思いますが、クイックタッチアップよりもはるかに多いようで、元の作者を怒らせたくありません。それでも、この回答リストは犬の混乱の夕食であり、おそらく私の投稿を殺すのがとにかく最善でしょう。
エドウィンバック

8
  1. Tomcatのbinディレクトリからtomcat7wを開くか、スタートメニューでMonitor Tomcatと入力します(さまざまなサービス情報が表示されたタブ付きウィンドウが開きます)。
  2. 「Javaオプション」テキスト領域に次の行を追加します。

    -XX:MaxPermSize=128m
  3. 初期メモリプールを1024に設定します(オプション)。
  4. 最大メモリプールを1024に設定します(オプション)。
  5. OKをクリックします。
  6. Tomcatサービスを再起動します。

6

perm genスペースエラーは、コードを実行するためにjvm提供スペースではなく大きなスペースを使用したことが原因で発生します。

UNIXオペレーティングシステムにおけるこの問題の最良の解決策は、bashファイルの一部の構成を変更することです。次の手順で問題を解決します。

gedit .bashrc端末でコマンドを実行します。

JAVA_OTPS次の値で変数を作成します。

export JAVA_OPTS="-XX:PermSize=256m -XX:MaxPermSize=512m"

bashファイルを保存します。端末でコマンドexec bashを実行します。サーバーを再起動します。

このアプローチがあなたの問題に役立つことを願っています。8より前のバージョンのJavaを使用すると、この問題が発生することがあります。しかし、Java 8を使用する場合、問題は発生しません。


5

実際のメモリリークが発生している場合は、Permanent Generationサイズを大きくするか、GCパラメータを調整しても効果がありません。アプリケーションまたはそれが使用するいくつかのサードパーティライブラリの場合、リーククラスローダーは、このリークを見つけて修正することが唯一の現実的かつ永続的な解決策です。あなたを助けることができるいくつかのツールがあり、最近の1つはPlumbrです。これは、必要な機能を備えた新しいバージョンをリリースしたばかりです。


5

また、webappでlog4jを使用している場合は、log4j ドキュメントのこの段落を確認してください。

を使用している場合PropertyConfigurator.configureAndWatch("log4j.properties")、Webアプリケーションをアンデプロイするときにメモリリークが発生するようです。


4

私は、Hibernateは+のEclipse RCPの組み合わせを持って使用してみました-XX:MaxPermSize=512m-XX:PermSize=512m、それは私のために働いているようです。


4

セット-XX:PermSize=64m -XX:MaxPermSize=128m。後で、増加を試すこともできますMaxPermSize。うまくいくことを願っています。私も同じように機能します。設定だけでMaxPermSizeはうまくいきませんでした。


4

私はいくつかの答えを試しましたが、最終的に仕事をしたのはpomのコンパイラプラグインのこの構成だけでした:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <fork>true</fork>
        <meminitial>128m</meminitial>
        <maxmem>512m</maxmem>
        <source>1.6</source>
        <target>1.6</target>
        <!-- prevent PermGen space out of memory exception -->
        <!-- <argLine>-Xmx512m -XX:MaxPermSize=512m</argLine> -->
    </configuration>
</plugin>

これがお役に立てば幸いです。


「argLine」はmaven-compiler-plugin 2.4では認識されません。エラーが発生する "compilerArgument"のみをサポートします:<compilerArgument> -XX:MaxPermSize = 256m </ compilerArgument> [ERROR] javacの実行に失敗しましたが、エラーを解析できませんでした:javac:無効なフラグ:-XX:MaxPermSize = 256m :javac <オプション> <ソースファイル>
Alex

コンパイルフェーズでpermgenが不足している場合は、maven-compiler-pluginに<compilerArgument>を設定します。ユニットテストは、permgenセットが不足している場合は、<argLine>のmaven-確実な-プラグインで
QWERTY配列の

4

私にとってもこれを解決しました。しかし、サーブレットの再起動時間がはるかに悪いことに気づきました。そのため、本番環境では改善されたものの、開発における一種の障害になりました。


3

メモリの構成は、アプリの性質によって異なります。

何してるの?

処理されたトランザクションの量はいくらですか?

どのくらいのデータを読み込んでいますか?

おそらく、あなたはあなたのアプリをプロファイリングし、あなたのアプリからいくつかのモジュールをクリーンアップし始めることができます。

どうやらこれは、アプリケーションを数回再デプロイした後に発生する可能性があります

Tomcatにはホットデプロイがありますが、メモリを消費します。ときどきコンテナを再起動してみてください。また、プロダクションモードで実行するために必要なメモリの量を知る必要があります。これは、その研究にとって良い時期のようです。


3

彼らは、Tomcatの最新のリビジョン(6.0.28または6.0.29)が、サーブレットを再デプロイするタスクをより適切に処理すると言ってます。


3

私はまったく同じ問題に遭遇しましたが、残念ながら、提案された解決策のどれも実際にはうまくいきませんでした。この問題はデプロイメント中には発生せず、ホットデプロイメントも行っていません。

私の場合、問題は、(休止状態を介して)データベースに接続しているときに、Webアプリケーションの実行中の同じ時点で毎回発生しました。

このリンクこれも前述)は、問題を解決するのに十分な内部を提供しました。jdbc-(mysql)-driverをWEB-INFからjre / lib / ext /フォルダーに移動すると問題が解決したようです。新しいJREにアップグレードするとドライバーの再インストールが必要になるため、これは理想的なソリューションではありません。同様の問題を引き起こす可能性のある別の候補はlog4jです。そのため、これも移動することができます。


ドライバーをjre / lib / extに含めたくない場合は、コンテナーのスタートアップクラスパスにドライバーを含めることで同じ結果が得られる可能性があります。java -cp /path/to/jdbc-mysql-driver.jar:/path/to/container/bootstrap.jar container.Start
Scot

3

そのような場合の最初のステップは、GCがPermGenからクラスをアンロードできるかどうかを確認することです。標準のJVMはこの点ではかなり保守的です。クラスは永遠に生きるために生まれています。したがって、ロードされると、コードがそれらを使用していない場合でも、クラスはメモリに残ります。これは、アプリケーションが多くのクラスを動的に作成し、生成されたクラスが長期間必要ない場合に問題になる可能性があります。このような場合、JVMがクラス定義をアンロードできるようにすると便利です。これは、起動スクリプトに構成パラメーターを1つだけ追加することで実現できます。

-XX:+CMSClassUnloadingEnabled

デフォルトではfalseに設定されているため、これを有効にするには、Javaオプションで次のオプションを明示的に設定する必要があります。CMSClassUnloadingEnabledを有効にすると、GCはPermGenもスイープし、使用されなくなったクラスを削除します。このオプションは、UseConcMarkSweepGCも以下のオプションを使用して有効になっている場合にのみ機能することに注意してください。したがって、ParallelGCを実行する場合、または、シリアルGCを禁止する場合は、次のように指定してGCをCMSに設定していることを確認してください。

-XX:+UseConcMarkSweepGC

3

Tomcatにさらに多くのメモリを割り当てることは適切な解決策ではありません。

正しい解決策は、コンテキストが破棄されて再作成された後にクリーンアップを行うことです(ホットデプロイ)。解決策は、メモリリークを停止することです。

Tomcat / Webappサーバーがドライバー(JDBC)の登録解除に失敗したことを通知している場合は、それらを登録解除します。これにより、メモリリークが停止します。

ServletContextListenerを作成して、web.xmlで構成できます。次にServletContextListenerのサンプルを示します。

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.Logger;

import com.mysql.jdbc.AbandonedConnectionCleanupThread;

/**
 * 
 * @author alejandro.tkachuk / calculistik.com
 *
 */
public class AppContextListener implements ServletContextListener {

    private static final Logger logger = Logger.getLogger(AppContextListener.class);

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        logger.info("AppContextListener started");
    }

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        logger.info("AppContextListener destroyed");

        // manually unregister the JDBC drivers
        Enumeration<Driver> drivers = DriverManager.getDrivers();
        while (drivers.hasMoreElements()) {
            Driver driver = drivers.nextElement();
            try {
                DriverManager.deregisterDriver(driver);
                logger.info(String.format("Unregistering jdbc driver: %s", driver));
            } catch (SQLException e) {
                logger.info(String.format("Error unregistering driver %s", driver), e);
            }

        }

        // manually shutdown clean up threads
        try {
            AbandonedConnectionCleanupThread.shutdown();
            logger.info("Shutting down AbandonedConnectionCleanupThread");
        } catch (InterruptedException e) {
            logger.warn("SEVERE problem shutting down AbandonedConnectionCleanupThread: ", e);
            e.printStackTrace();
        }        
    }
}

そして、あなたはあなたのweb.xmlでそれを設定します:

<listener>
    <listener-class>
        com.calculistik.mediweb.context.AppContextListener 
    </listener-class>
</listener>  

2

「それら」は間違っています。6.0.29を実行していて、すべてのオプションを設定した後でも同じ問題が発生します。ティム・ハウランドが上で述べたように、これらのオプションは避けられないことを先延ばしにするだけです。再デプロイするたびにではなく、エラーが発生する前に3回再デプロイできます。


2

ケースであなたもパラメータを設定した後、EclipseのIDEでこれを取得している --launcher.XXMaxPermSize-XX:MaxPermSizeなど、あなたが同じエラーを取得している場合は、まだ、それが最も可能性が高い日食がいくつかによってインストールされていたであろうJREのバグのあるバージョンを使用していることですサードパーティのアプリケーションとデフォルトに設定。これらのバグのあるバージョンはPermSizeパラメータを取得しないため、設定した値に関係なく、引き続きこれらのメモリエラーが発生します。したがって、eclipse.iniに次のパラメーターを追加します。

-vm <path to the right JRE directory>/<name of javaw executable>

また、Eclipseの設定でデフォルトのJREがJavaの正しいバージョンに設定されていることを確認してください。


2

私にとってうまくいった唯一の方法は、JRockit JVMでした。MyEclipse 8.6を持っています。

JVMのヒープには、実行中のJavaプログラムによって生成されたすべてのオブジェクトが格納されます。Javaはnew演算子を使用してオブジェクトを作成し、新しいオブジェクトのメモリは実行時にヒープに割り当てられます。ガベージコレクションは、プログラムによって参照されなくなったオブジェクトに含まれるメモリを自動的に解放するメカニズムです。


2

私は同様の問題を抱えていました。私のものは、JDK 7 + Maven 3.0.2 + Struts 2.0 + Google GUICE依存性注入ベースのプロジェクトです。

mvn clean packageコマンドを実行しようとすると、次のエラーが表示され、「ビルド失敗」が発生しました

org.apache.maven.surefire.util.SurefireReflectionException:java.lang.reflect.InvocationTargetException; ネストされた例外はjava.lang.reflect.InvocationTargetException:null java.lang.reflect.InvocationTargetExceptionです。原因:java.lang.OutOfMemoryError:PermGen space

上記の役立​​つヒントやテクニックをすべて試しましたが、残念ながらどれもうまくいきませんでした。私のために働いたことは以下のステップバイステップで説明されています:=>

  1. pom.xmlに移動します
  2. 検索する <artifactId>maven-surefire-plugin</artifactId>
  3. 新しい<configuration>要素を追加し、次に<argLine>サブ要素を追加します。次に-Xmx512m -XX:MaxPermSize=256m示すようにパスを渡します=>

<configuration> <argLine>-Xmx512m -XX:MaxPermSize=256m</argLine> </configuration>

それが役に立てば幸いです、幸せなプログラミング:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.