Tomcat application gets a java.lang.OutOfMemoryError

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/ -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 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?
LVL 17
Who is Participating?
fargoConnect With a Mentor Commented:
128m for a 1GB machine is still low. In any decent production env. you should atleast keep it to 512m, so that even if there is any memory leaks, one can still be productive.

Eclipse has a plugin called Eclipse Profiler at 
rama_krishna580Connect With a Mentor Commented:

There must be an instant loop, which creates big objects, You should check Your code, or Your application is so heavy,
that it uses the memory JVM is allowed to use. To increase the amount of JVM memory,
pass an argument to java an argument:

java -Xmx256M ....... or 512 based on heapsize

This sets the ammount of memory to 256MB, while by default java uses 64MB

rstaveleyAuthor Commented:
Thanks for the swift response, rama_krishna580. With only 1GB on the server, I've increased it now to a conservative -Xmx128m and will increase it again if I get bitten again. Given the timescale I'm only realistically looking for a work-around rather than a solution. It is hard to believe that it is anything fast-acting bearing in mind that the loss of heap has appeared to be quite steady since Friday. I expect that there are some persistent caches get populated when the obsolete bits of the site are accessed.

Do you know of any monitoring tools that I could graph freeMemory(), totalMemory() and maxMemory() from Runtime.getRuntime() to get a picture of the extent of the problem?
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Mayank SConnect With a Mentor Associate Director - Product EngineeringCommented:
rstaveleyAuthor Commented:
There are some great suggestions here. Bearing in mind that I'm increasing from the default 64M, I hope that I've got some leeway before I start needing the likes of -XX:+AggressiveHeap, but I'll certainly bear it in mind.

fargo/mayankeagle, thanks for putting me onto profilers. I'll have a go with because that seems to be limited to the specific area of my concern and therefore should hopefully be quicker to get up to speed with. The Eclipse plugin looks wonderful, but I think there'd be more familiarisation required, because I'm not an Eclipse user.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.