Sunday, July 8, 2012

Getting around Tomcat out-of-memory issues

“Server running out of memory” is one of the common causes for webserver crashing experienced by most of the Web Application Admins, yet it’s really easy for anyone to determine it happens due to java heap space limitation (JVM memory allocation).  This could lead to false conclusions such as application needing more heap space or application should be clustered/load balanced to provide high availability. On the other hand, when the service is running out of memory it could appear as a memory leak within the application and eventually it can end up with development team testing it.
This post covers simple steps to fine-tune your system memory according to your application requirement, prior to deciding on any infrastructure changes that would be considered.

OutOfMemoryError

JVM throws this error when there is no space in memory for JVM to continue working. This happens mostly while you try to create more objects when there is no space in the heap to allocate as needed.
There are two main causes for this error.
1.  Java heap space limitation.
2.  Java perm gen limitation

Java heap limitation

This is the most commonly known fact related to the out-of-memory issue. You can tweak heap space settings using –Xmx (Maximum heap size) and –Xms (Initial heap size) parameters. In general, if you have more memory the less frequent it needs to be garbage collected. So you could expect applications to run faster when there is more memory available. But from GC’s perspective it will have to work on a larger memory than usual. It’s just like for a floor cleaner you have a bigger floor to clean than he usually does. This in turn can decrease overall performance of your application so you should tweak these settings consciously.
Example :
    -Xmx1536m
    -Xms1024m

Java Permanent Generation limitation

This is where JVM store meta data information about classes, methods (on Eden heap and Tenured heap) and other java primitives. By default this value is set to 64m. Most of the time it’s not sufficient for many applications. So it’s really important to change this setting and provide some space for perm gen to work on. Unlike xmx and xms, you have to use “=” to define this setting. Also you can use additional JVM flags “-XX:+CMSClassUnloadingEnabled” and “-XX:+CMSPermGenSweepingEnabled”. This will enforce sweeping through the permanent generation to release unused references to some extent.
Example :
    -XX:PermSize=64M
    -XX:MaxPermSize=256m
    -XX:+CMSPermGenSweepingEnabled
    -XX:+CMSClassUnloadingEnabled
Generally many Application Admins are aware of heap space settings. Yet there are many instances where perm gen settings have gone unnoticed. It’s really important to fine-tune your application for permanent generation heap as it could be a good reason for your out-of-memory errors