将 war 从 Jenkins 部署到 Tomcat 时出现 OutOfMemoryError
OutOfMemoryError while deploying a war from Jenkins to Tomcat
我使用以下 shell 命令从 Jenkins 部署我的应用程序:
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
经常在开始定期构建时 Tomcat 内存不足并出现以下错误。
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)
我有一个 windows 环境并通过 cygwin 执行 shell。
shell 命令有问题,还是由于内存泄漏?我引入睡眠是为了给应用程序一些时间来取消部署。我从来没有尝试过增加睡眠时间。
谢谢。
因为异常表明您的问题来自填充 PermGen space。它是内存的一部分,Java 存储关于您的 类 的元数据(假设您加载的 类 的代码)。当您部署新的网络应用程序时,您会添加新的 类 并增加 PermGen 的负载。更糟糕的是,当您在 90% 的情况下重新部署相同的应用程序时,使用的 类 的先前版本保留在内存中,因此您不会从 PermGen 释放 'old' 内存,而只是添加到它(90% 的估计来自使用数据库驱动程序,使用 ThreadLocal 的框架,调度程序线程......实际上它几乎一直发生)。
默认的 permgen 太小(比如 64M 或其他荒谬的东西)。以更高的值开始 tomcat,您可以通过将 JVM 选项传递给 tomcat 来实现,例如:
JAVA_OPTS = -XX:MaxPermSize=512m -Xmx4024m
(首先将 perm 大小设置为 512MB,然后将堆大小设置为 4G,这对于现代系统来说很好)。
你在开始之前设置这个变量 tomcat,或者(我更喜欢这样,你可以修改你的 /bin/catalina 脚本以始终在那里设置它们,这样你就不会 'forget' 如果你再次开始你的 tomcat 他们。
从 tomact 7 开始,当您取消部署应用程序时,tomcat 日志会显示应用程序在内存中的警告(并填满您的 PermGen),您可能需要检查它们并尝试修复一些问题(更新框架,正确关闭线程池...)
我使用以下 shell 命令从 Jenkins 部署我的应用程序:
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
经常在开始定期构建时 Tomcat 内存不足并出现以下错误。
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)
我有一个 windows 环境并通过 cygwin 执行 shell。
shell 命令有问题,还是由于内存泄漏?我引入睡眠是为了给应用程序一些时间来取消部署。我从来没有尝试过增加睡眠时间。
谢谢。
因为异常表明您的问题来自填充 PermGen space。它是内存的一部分,Java 存储关于您的 类 的元数据(假设您加载的 类 的代码)。当您部署新的网络应用程序时,您会添加新的 类 并增加 PermGen 的负载。更糟糕的是,当您在 90% 的情况下重新部署相同的应用程序时,使用的 类 的先前版本保留在内存中,因此您不会从 PermGen 释放 'old' 内存,而只是添加到它(90% 的估计来自使用数据库驱动程序,使用 ThreadLocal 的框架,调度程序线程......实际上它几乎一直发生)。
默认的 permgen 太小(比如 64M 或其他荒谬的东西)。以更高的值开始 tomcat,您可以通过将 JVM 选项传递给 tomcat 来实现,例如:
JAVA_OPTS = -XX:MaxPermSize=512m -Xmx4024m
(首先将 perm 大小设置为 512MB,然后将堆大小设置为 4G,这对于现代系统来说很好)。
你在开始之前设置这个变量 tomcat,或者(我更喜欢这样,你可以修改你的 /bin/catalina 脚本以始终在那里设置它们,这样你就不会 'forget' 如果你再次开始你的 tomcat 他们。
从 tomact 7 开始,当您取消部署应用程序时,tomcat 日志会显示应用程序在内存中的警告(并填满您的 PermGen),您可能需要检查它们并尝试修复一些问题(更新框架,正确关闭线程池...)