Lift と Jetty に関する PermGen の問題
-
12-09-2019 - |
質問
私は標準の Lift プラットフォーム (Maven と Jetty) で開発しています。繰り返し(数日に1回)次のようなメッセージが表示されます。
Exception in thread "7048009@qtp-3179125-12" java.lang.OutOfMemoryError: PermGen space
2009-09-15 19:41:38.629::WARN: handle failed
java.lang.OutOfMemoryError: PermGen space
これは私の開発環境でのことです。サーバーを再起動し続けることができるので問題ありません。導入時にはこのような問題は発生していないため、実際の問題ではありません。ただ興味があるだけです。
JVM についてはあまり詳しくありません。永続世代メモリはクラスやインターンされた文字列などのためのものであると考えるのは正しいと思いますか?私の記憶では、.NET メモリ モデルと少し混同されています...
このようなことが起こっている理由はありますか?デフォルトは異常に低いだけですか?それは、Scala が Function オブジェクトや同様の FP オブジェクト用に作成する必要があるすべての補助オブジェクトと関係があるのでしょうか?新しく書いたコードで Jetty を再起動するたびに (数分ごとに)、クラスなどが再ロードされると思います。でも、そうであっても、そんなにたくさんあるわけがないじゃないですか。そして、JVM は多数のクラスを処理できるべきではないでしょうか?
乾杯
ジョー
解決
から この郵便受け:
この例外は 1 つの単純な理由で発生しました。
のpermgenspace
には、メソッド、フィールド、アノテーション、静的変数などのクラス プロパティが含まれます。は Java VM に保存されますが、このスペースにはガベージ コレクターによってクリーンアップされないという特殊性があります。したがって、Web アプリで多数のクラス (クラスの動的な世代を考えています) を使用または作成している場合、この問題が発生する可能性があります。この例外を取り除くのに役立ついくつかの解決策を次に示します。
-XX:+CMSClassUnloadingEnabled
:この設定により、permgenspace でのガベージ コレクションが有効になります。-XX:+CMSPermGenSweepingEnabled
:ガベージ コレクターがメモリからクラスさえも削除できるようにします-XX:PermSize=64M -XX:MaxPermSize=128M
:permgenspace に割り当てられるメモリの量を増やします
これが役立つかもしれません。
2012 年 7 月編集 (ほぼ 3 年後):
オンドラ・ジシュカ コメント(上記の回答を更新しました):
JVM 1.6.0_27 には次のように書かれています。使ってください:
CMSClassUnloadingEnabled
(CMS GC使用時にクラスアンロードが有効かどうか)- 代わりに
CMSPermGenSweepingEnabled
将来
全文を見る ホットスポット JVM オプション - 完全なリファレンス ミスターのために。
他のヒント
走行中にこれを見たら mvn jetty:run
、 をセットする MAVEN_OPTS
.
Linuxの場合:
export MAVEN_OPTS="-XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M"
mvn jetty:run
Windowsの場合:
set "MAVEN_OPTS=-XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M"
mvn jetty:run
今は大丈夫なはずです。そうでない場合は増やしてください -XX:MaxPermSize
.
これらを環境に永続的に配置することもできます。
Linux の場合は、
export
への行~/.bashrc
Windows の場合は、 を押します。
Win-key + PrintScreen
, 、 じゃ、行けAdvanced > Environment
。こちらも参照 http://support.microsoft.com/kb/310519.
これは、クラスのリロードです。あなたがなどのライブラリの多くを使用している場合は、クラスの合計が急速に各再起動のために成長します。リロード時にメモリ消費の概要を取得するためにVisualVMのとあなたの桟橋のインスタンスを監視してみます。
メーリングリスト( http://groups.google.com/group/liftweb/)リフトのための公式サポートフォーラムで、あなたは、より良い答えを得ることができるようになります場所。私は(あなたは多くの詳細には触れません)あなたのdevのセットアップの詳細を知らないが、私はあなたが実際にそれを再起動せずに桟橋であなたの戦争をリロードしていると仮定します。リフトは、(上記VonCによって示唆されるように)動的なクラスの生成を行っていないが、Scalaは別のクラスとして、各クロージャをコンパイル。あなたは数日間にわたってあなたのコードにクロージャを追加したり削除している場合、それはあまりにも多くのクラスがロードされ、決してアンロードされ、パーマスペースを占有されている可能性があります。私はあなたが上VonCで述べたオプションのJVMオプションを有効にして、彼らは助けるかどうか見ることをお勧めしたい。
永久的な世代があるカスタムクラスローダーのように収集されます。
あなたが展開している内容に応じて、パーマ世代の設定を低くすることができます。一部のアプリケーションおよび/またはコンテナの組み合わせは、いくつかのメモリリークが含まれていませんので、アプリをアンデプロイ取得するときに時々、クラスローダのようないくつかのものは、あなたが持っているエラーを生成するので、パーマスペースを埋め、その結果、収集されません。
残念ながら、現在、この場合、最良のオプションは、次のJVMフラグ(192メートルパーマサイズの一例)とパーマスペースMAX個までです。
-XX:MaxPermSize=192M (or 256M)
他のオプションは、コンテナやフレームワークのいずれかが、メモリリークが発生していないことを確認することです。