我遇到了麻煩熱部署Spring-MVC 4.0(不是SpringBoot)Web應用程序。我試圖去xml-less,只是使用JavaConfig。 OutOfMemoryErrors導致我刪除web.xml或當我部署一個空的web.xml只有一個空的元素。這不會發生每次應用程序是熱部署和成功的熱部署後,應用程序不正常工作,但經過三,四個熱部署這種配置中出現以下錯誤:將SpringMVC應用程序熱部署到Tomcat7時出現OutOfMemoryError - 與log4j2可能存在關聯
Jul 03, 2015 10:49:43 AM org.springframework.web.context.ContextLoader initWebApplicationContext
SEVERE: Context initialization failed
java.lang.OutOfMemoryError: PermGen space
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:220)
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:615)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:465)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5014)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5524)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1081)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1877)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Jul 03, 2015 10:49:44 AM org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor run
SEVERE: Unexpected death of background thread ContainerBackgroundProcessor[StandardEngine[Catalina]]
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:816)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:488)
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1655)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:328)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1374)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1546)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1556)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1524)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "ContainerBackgroundProcessor[StandardEngine[Catalina]]" 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:816)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:488)
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1655)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:328)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1374)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1546)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1556)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1524)
at java.lang.Thread.run(Thread.java:745)
很明顯,內存以這種配置泄漏。
這個Web應用程序使用Log4j2可能相關也可能不相關。 An earlier Stack Overflow question探討了這一點。如果Web應用程序只使用以下最低的web.xml
<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>file:///path/to/log4j2.xml</param-value>
</context-param>
</web-app>
那麼Web應用程序可以熱部署遍地沒有得到這些錯誤。
任何人都可能冒險猜測這裏會發生什麼?
更新: - 請參閱下面的@Makoton和我之間的討論。看起來很可能存在與從應用程序加載log4j2(Java Config方式)或從web.xml加載它(傳統方式)相關的垃圾收集問題。請參閱this article,其中揭示了針對此問題的「經典」堆棧溢出建議(類似於Makoton引用的建議)。
這讓我想起SpringBoot,據我瞭解,它將Tomcat加載爲應用程序的一部分。這可能是解決這個問題的方法之一。
你的意思是說或許「如果元素不存在於web.xml中或者如果沒有web.xml」,那麼錯誤是?那是我的情況。我添加了log4j2配置,因爲這是我可以走的唯一途徑。這聽起來像你說我可以把log4j2配置放回到Spring java配置中,並且只在web.xml中有這個東西。或者我可以等待修復。我有這個好嗎? –
如果缺少web.xml會導致log4j無法找到servlet上下文名稱,那麼是的。我沒有嘗試與春天。 –
我會確認以下情況:1)如果display-name不包含在web.xml中,但包含log4jConfiguration上下文參數,則不會發生內存泄漏,也不會發生關於缺少配置的錯誤消息。 2)如果包含顯示名稱和log4jConfiguration c.p.包括在內,與之前一樣。 3)如果web.xml中沒有包含參數,則會發生內存泄漏。 4)如果web.xml中包含display-name,web.xml中沒有log4j config,但是包含在java中的編程log4j config,則沒有mem泄漏,最初在日誌中看到丟失的配置錯誤msg,但javaconf使它正確。 –