rd22
rd22

Reputation: 1032

OutOfMemoryError while deploying a war from Jenkins to Tomcat

I deploy my application from Jenkins my using the following shell command:

rm -rf E:/FooTomcat/apache-tomcat-7.0.55/webapps/foo-web;
rm -rf E:/FooTomcat/apache-tomcat-7.0.55/webapps/foo-web.war;
sleep 2;
cp foo-web/target/foo-web-0.0.1-SNAPSHOT.war E:/FooTomcat/apache-tomcat-7.0.55/webapps/foo-web.war

Often when the periodic build is started the Tomcat runs out of memory giving the following error.

Feb 13, 2015 3:59:58 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deploying web application archive E:\FooTomcat\apache-tomcat-7.0.55\webapps\foo-web.war
Feb 13, 2015 4:00:06 PM org.apache.catalina.startup.HostConfig deployWARs
SEVERE: Error waiting for multi-thread deployment of WAR files to complete
java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: PermGen space
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:188)
    at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:818)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:488)
    at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1658)

I have a windows environment and executing the shell through cygwin.

Is someting wrong with the shell command, or is it due to some memory leak? I introduced the sleep to give some time for the application to undeploy. I have never tried by increasing the sleep duration.

Thanks.

Upvotes: 2

Views: 3612

Answers (1)

Zielu
Zielu

Reputation: 8552

As the exception indicates your problem comes from filling up the PermGen space. It is a part of memory where Java stores the metadata about your classes (let's say the code of your loaded classes). When you deploy a new web-app you add new classes and increase the load of PermGen. What is worse, when you re-deploy the same app in 90% of the cases, the previous versions of the used classes stays in the memmory so you do not release the 'old' memory from PermGen but just add to it (the 90% estimation comes from using DataBase drivers, frameworks which uses ThreadLocal, Scheduler threads ... in reality it happens almost all the time).

The default permgen is too small (like 64M or something as ridiculous). Start tomcat with higher values, you do it by passing to tomcat the JVM options, for example:

JAVA_OPTS = -XX:MaxPermSize=512m -Xmx4024m

(first set the perm size to 512MB second the heap size to 4G, which is fine for modern system).

You set this variable before you start tomcat, or (I prefer it that way, you can modify your /bin/catalina script to always have them set up there, that way you will not 'forget' them if you start your tomcat again).

From tomact 7, when you undeploy app, the tomcat logs show warnings of apps that stays in memmory (and fill up your PermGen), you may want to check them and try to fix some problems (updating frameworks, shuting down properly your threads pool ...)

Upvotes: 3

Related Questions