Tomcat application gets a java.lang.OutOfMemoryError
Posted on 2006-05-01
I've inherited a highly customised and long-in-the-tooth Struts-based application. I ported this in short order from Weblogic 5.1 + Solaris VM Solaris JDK1.2 + Oracle 8 + load balancing (shared server) to Tomcat 5.5 + Sun J2SE JDK1.5 + PostgreSQL + no load balancing (dedicated server with local database), and am still patching bits and pieces. It seems to be functional enough to service the essential business requirements, but the site collapsed this morning with a java.lang.OutOfMemoryError on every page access, which I had to remedy by restarting Tomcat.
Trawling through the logs, I can see java.lang.OutOfMemoryError thrown increasingly when JSPs were compiled (actually during the .java compilation). The pages concerned aren't really a major concern to me, because they are clearly someone or something sniffing around the site looking at pages with obsolete content. I can live with the HTTP/500 errors on those in the short term. However, the frequency of their occurrence increased from the first one and only occurrence on April 28th to today's complete loss of service on 1st May. On 29th-30th we saw them start to take effect for compilation of small JSPs and ultimately we saw java.lang.OutOfMemoryError for every page access the morning regardless of whether it needs to compile or not.
May 1, 2006 3:25:02 AM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.OutOfMemoryError: Java heap space
Presumably we are leaving ourselves with less and less available heap for compilation as the application is left to run. I have debug="1" and autoDeploy="true", which reflects the short-order/last-minute nature of this port - or perhaps it just reflects my own naivety! I am using Sun's JDK1.5 compiler and VM rather than Tomcat's recommended Eclipse JDT compiler, because I am using generics.
Tomcat is running with the VM's default 64M, which presumably ought to be increased (the server is a 1GB Dual Xeon).
Here's the start-up:
/usr/java/jdk1.5.0_06/bin/java -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=/usr/java/apache-tomcat-5.5.15/conf/logging.properties -Djava.endorsed.dirs=/usr/java/apache-tomcat-5.5.15/common/endorsed -classpath :/usr/java/apache-tomcat-5.5.15/bin/bootstrap.jar:/usr/java/apache-tomcat-5.5.15/bin/commons-logging-api.jar -Dcatalina.base=/usr/java/apache-tomcat-5.5.15 -Dcatalina.home=/usr/java/apache-tomcat-5.5.15 -Djava.io.tmpdir=/usr/java/apache-tomcat-5.5.15/temp org.apache.catalina.startup.Bootstrap start
Bearing in mind that I need this site to be stable over the next 7 days, what's the most sensible approach to work around my memory leak? Increase heap? Automatically bounce the site in the event we see a java.lang.OutOfMemoryError??? Any suggestions, gentlefolk?