/h/
1,获取dump
2,从dump找到正在运行的线程所属class
3,在myeclise 开启debug模式,给正在运行的方法加上断点
4,这时你会发现当停止application时,有一个线程还没有停止掉
5,在 AppContextListener 进行contextDestroyed时,要加一段额外的代码,用来我们关闭tomcat的时候可以同时关闭此线程
例如此例:
在tomcat7+quartz1.8/1.7 + spring3.0.5做定时任务的时候 , 当关闭tomcat时抛异常"严重: The web application [] appears to have started a thread named [Thread-":
ar 27, 2013 6:05:35 PM pause
INFO: Pausing ProtocolHandler ["http-nio-8082"]
Mar 27, 2013 6:05:35 PM stopInternal
INFO: Stopping service Catalina
Mar 27, 2013 6:05:35 PM clearReferencesThreads
SEVERE: The web application [/****] appears to have started a thread named [startQuertz_Worker-1] buthas failed to stop it. This is very likely to create a memory leak.
Mar 27, 2013 6:05:35 PM clearReferencesThreads
SEVERE: The web application [/****] appears to have started a thread named [startQuertz_Worker-2] buthas failed to stop it. This is very likely to create a memory leak.
Mar 27, 2013 6:05:35 PM clearReferencesThreads
SEVERE: The web application [/****] appears to have started a thread named [startQuertz_Worker-3] buthas failed to stop it. This is very likely to create a memory leak.
Mar 27, 2013 6:05:35 PM clearReferencesThreads
原因:tomcat在shutdown做清理工作的时候没能等待quartz完成cleanShutdown。就是tomcat太心急了,说 “quartz , 我关门了,你走吧!”,还没等quartz反应过来,就要关大门,这时发现 “quartz , 你怎么还在这儿呀!”。
解决办法:自己实现一个ServletContextListener,在contextDestroyed的时候主动调用quartz schedular的shutdown方法,并且主线程sleep一会儿.
代码:
public class QuartzContextListener implements ServletContextListener {
/*
* 测试代码写得随便
*
* @#contextDestroyed(.
* ServletContextEvent)
*/
@Override
public void contextDestroyed(ServletContextEvent arg0) {
WebApplicationContext webApplicationContext = (WebApplicationContext) arg0
.getServletContext()
.getAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
startQuertz = () webApplicationContext
.getBean("startQuertz");
if(startQuertz != null) {
();
}
try {
(1000);
} catch (InterruptedException e) {
();
}
}
/*
* (non-Javadoc)
*
* @see
* #contextInitialized(
* .ServletContextEvent)
*/
@Override
public void contextInitialized(ServletContextEvent arg0) {
<span style="white-space:pre"> </span>//不做任何事情
}
}
最后在 配置QuartzContextListener。
注意:如果tomcat在Dameon模式下,以上方法不起作用,请参考:
/tomcat/MemoryLeakProtection