【发布时间】:2013-05-04 02:02:30
【问题描述】:
在基于Spring framework 3.0.5 的Web 应用程序的stop 或undeploy/redeploy 上,在Tomcat7's catalina.out 中记录了以下错误:
SEVERE: The web application [/nomination##1.0-qa] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@4f43af8f]) and a value of type [org.springframework.security.core.context.SecurityContextImpl] (value [org.springframework.security.core.context.SecurityContextImpl@ffffffff: Null authentication]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
我最初想在那里实现 ServletContextListener 和 close() 上下文。但是,发现实现ServletContextListener的ContextLoaderListener在web.xml中是这样设置的:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
来自 Javadocs:
**contextDestroyed**
public void contextDestroyed(ServletContextEvent event)
Close the root web application context.
Specified by:
contextDestroyed in interface ServletContextListener
那么,我的问题是为什么 ContextLoaderListener.contextDestroyed() 没有完全释放 ThreadLocal?
我们遇到了PermGen 错误,并在调查时发现了这一点。有几个地方有类似下面的代码:
ApplicationContext context = WebApplicationContextUtils
.getWebApplicationContext(se.getSession().getServletContext());
MyBeanClass x = context.getBean(
"myBean", MyBeanClass.class);
x.someMethod();
我想知道上面的 sn-p 是否正在停止干净关机? 任何指针将不胜感激。
【问题讨论】:
-
在将根应用程序上下文一分为二时,我开始遇到此错误。我现在有一个用于引导程序的根上下文(具有相同的两个子 servlet 上下文),而不是具有两个子 servlet 上下文的单个根上下文,并且稍后我以编程方式创建了一个子上下文。在此设计中,安全配置继续保留在根应用程序上下文中,但现在出现了泄漏警告。显然,在我的情况下,这与将根应用程序上下文一分为二有关。
-
@Mihai Danila 我只有一个应用程序上下文。
-
您的安全上下文设置如何?
-
您取消注册驱动程序了吗? @Override public void contextDestroyed(ServletContextEvent arg0) { Enumeration
drivers = DriverManager.getDrivers(); while (drivers.hasMoreElements()) { Driver driver = drivers.nextElement();尝试 { DriverManager.deregisterDriver(driver); } 捕捉 (SQLException e) { } } } -
@MihaiDanila 我知道有点晚了,但你能分享你的应用程序 ctx 吗?谢谢。
标签: spring-mvc memory-leaks permgen servlet-listeners servletcontextlistener