Tomcat上で動くフリーで使えるグループウェア GroupSession2 を入れてしばらく使っていると「サーバエラーが発生しました。回線が込み合っている可能性があります。時間をおいて再接続してください。」というエラーが出ます。
まず Tomcat のログをチェックしてみました。(Tomcat6でCentOS上で動かしています。)
すると下記のようなログが。。
2009/12/21 13:01:59 org.apache.catalina.core.ApplicationDispatcher invoke
致命的: サーブレット jsp のServlet.service()が例外を投げました
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2882)
at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:515)
at java.lang.StringBuffer.append(StringBuffer.java:306)
at org.apache.jasper.compiler.JDTCompiler$1CompilationUnit.getContents(JDTCompiler.java:113)
at org.eclipse.jdt.internal.compiler.parser.Parser.getMethodBodies(Parser.java:8261)
at org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:612)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:392)
at org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:429)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:334)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:312)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:299)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:586)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at org.apache.struts.chain.commands.servlet.PerformForward.handleAsForward(PerformForward.java:113)
at org.apache.struts.chain.commands.servlet.PerformForward.perform(PerformForward.java:96)
at org.apache.struts.chain.commands.AbstractPerformForward.execute(AbstractPerformForward.java:54)
at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304)
at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
2009/12/21 13:02:16 org.apache.catalina.core.ApplicationDispatcher invoke
致命的: サーブレット jsp のServlet.service()が例外を投げました
java.lang.OutOfMemoryError: Java heap space
2009/12/21 13:02:22 org.apache.catalina.core.ApplicationDispatcher invoke
致命的: サーブレット jsp のServlet.service()が例外を投げました
java.lang.OutOfMemoryError: Java heap space
AbandonedObjectPool is used (org.apache.commons.dbcp.AbandonedObjectPool@841a34)
LogAbandoned: false
RemoveAbandoned: true
RemoveAbandonedTimeout: 600
2009/12/21 13:09:13 org.apache.catalina.core.ApplicationDispatcher invoke
致命的: サーブレット jsp のServlet.service()が例外を投げました
java.lang.OutOfMemoryError: Java heap space
2009/12/21 13:10:55 org.apache.catalina.core.ApplicationDispatcher invoke
2009/12/21 13:10:55 org.apache.catalina.core.ApplicationDispatcher invoke
OutOfMemoryError が連発です。
どうやらヒープが不足しているようです。
そういえば Tomcat のデフォルトで確保しているメモリって少なめだったんですよね。
TomcatManagerでサーバの状態をみるとJVMの状態はこんな感じでした。
Free memory: 0.19 MB Total memory: 63.56 MB Max memory: 63.56 MB
デフォルトの確保しているサイズは 64MB ということを思い出しました。空きメモリが0.2MBって。。。こりゃメモリ不足になるわけですわ。。
対処法としては Tomcat のメモリサイズを増やせばいいだけです。
GroupSessionのサポートによると Linux の場合 export CATALINA_OPTS='-Xmx256M -Xms128M' でできると書いてます。
(CentOS5.3 に Tomcat6 を入れてみた参照。)
なので、環境変数に書き込むのではなくこのスクリプトを編集します。
CATALINA_OPTSに下記のように設定を追加しました。(-server を付けるとエラーになったので -Xmx と -Xmx だけで事足りるようです)
CATALINA_OPTS=" -Xmx512m -Xms128m"
これでTomcatを再起動し、Manager からサーバの状態をみると下記のようになってました。
ちゃんと設定されてますね。
これでOutOfMemoryErrorが出なくなりました。
参考:
Java 入門 | JVM のメモリ構造 ヒープとはなんぞやという話です。
竹形誠司 ブログ:Java+MySQL+Tomcat:Tomcatがメモリを大食いする場合の対処 CATALINA_OPTS を別の場所にも記述できるようです。