为啥 Spring Context 没有优雅地关闭?
Posted
技术标签:
【中文标题】为啥 Spring Context 没有优雅地关闭?【英文标题】:Why Spring Context not gracefully closed?为什么 Spring Context 没有优雅地关闭? 【发布时间】: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) Enumerationhotdeploy 有很多你应该关心的问题:
1-注销数据库驱动程序see here。
2-关闭多任务应用程序中的任务:您可以在开发模式下将重启延迟将近 1 小时。
3-Kill context of spring:你在上面做了,但注意不要从 XML 中导入 XML。
4-Kill JVM 内存中存在的缓存对象:制作小对象,你在初始化吗 构造函数中的bean?将其更改为 none 构造函数以保持在方法范围内杀死它们! 类中调用bean的方法有多少?如果许多方法调用 bean 在从作用域中出来后不期望 java 杀死对象,jvm 会保留它以提高性能..,所以保持你的类小!。
你的代码怎么样?您是否在循环中声明变量?使用后你是=null列表还是对象?
5-你可以增加tomcat的启动时间和停止时间。
还可以将 rebel 或 springboot 项目视为助手。
【讨论】:
以上是关于为啥 Spring Context 没有优雅地关闭?的主要内容,如果未能解决你的问题,请参考以下文章
从 Shell 脚本优雅地关闭 Spring Boot 应用程序
为啥不尝试 I/O 就不可能检测到 TCP 套接字已被对等方优雅地关闭?