geek.conf.2

あるエンジニアの備忘録

java.lang.OutOfMemoryError: PermGen space

タイトルのエラーが$TOMCAT_HOME/logs/catalina.outに出力されスレッドが終了していた。。

このエラーのケツに注目。

これがPermGen spaceではなくJava Heap Spaceと出ればjavaのヒープ領域が不足し、
Out of Memoryエラーが起きてスレッドが終了していたと考えられる。

ヒープ領域が不足した場合はTomcatプロセスに割り当てられるOSが許す最大のメモリ領域
を指すので不足しているということはプログラムがメモリを開放させるよう組まれていないか、
メモリにゴミがたまりやすいよう設計されていないかなどプログラムを疑うことができます。

しかし、今回のばやい、PermGen spaceなのでこれは非ヒープ領域です。
じゃあこの領域はなんなんでしょう?

それはPermanent領域と言って主にJavaクラスのメタ情報が格納されます。

単純なプログラムではこの領域が圧迫されることはないですが、

tomcatなどのように、起動した後に外部のjarファイルを読み込んで実行する仕組みをもった
プログラムの場合には、起動した後にもPermanent領域への情報追加が行われる場合があ
ります。

これらのOut Of Memoryエラーを起こさないためにTomcatをチューニングする必要があります。

Tomcat
環境変数CATALINA_OPTSに以下のようにオプションを与えてTomcatを起動するといいですよ。

"-server -verbose:gc -XX:+PrintGCTimeStamps -Xmx512m -Xms512m -Xss512m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:SurvivorRatio=2 -XX:PermSize=128m -XX:MaxPermSize=128m -Xloggc:$CATALINA_HOME/logs/gc.`date '+%Y-%m-%d-%H%M%S'`
.log"

  • server → JVMサーバモードで動作させる。
  • verbose:gc → ガベージコレクションログ出力(簡易)
  • Xms → メモリ最大使用量
  • Xms → メモリ初期使用量
  • XX:NewSize → New世代領域使用量
  • XX:MaxNewSize → New世代領域最大使用量
  • XX:NewRatio → New世代領域とOld世代領域の比率(Old世代領域/New世代領域)
  • XX:SurvivorRatio → New世代領域とSurvivor領域の比率(Eden領域/From領域)
  • XX:PermSize → Permanent領域最大使用量
  • XX:MaxPermSize → Permanent領域初期使用量
  • Xss → スレッドスタックサイズ

他にもイロイロあるのでつづきは以下参照。



チューニングのためのJavaVM講座(後編)

TomcatのJVM(Java Virtual Machine)チューニング例 - 銀の鍵