小程序容器助力企业在金融与物联网领域实现高效合规运营,带来的新机遇与挑战如何管理?
478
2023-07-17
Spring关闭Tomcat Servlet容器时内存泄漏问题解决方案
这篇文章主要介绍了Spring关闭Tomcat Servlet容器时内存泄漏问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
出错信息
22-Sep-2017 06:19:51.064 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [license] appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
问题分析
servlet容器关闭时发现Quartz定时器线程还在执行,对其无所适从,不懂怎么办只能强行关闭。
解决思路
在关闭容器时的contextDestroyed事件里检测ServletContext里Quartz相关属性,找到Bean然后调用它的方法结束掉。
解决方法
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.apache.logging.log4j.web.Log4jWebSupport;
import org.quartz.impl.StdScheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
@WebListener
public class AppContextListener implements ServletContextListener
{
public void contextDestroyed(ServletContextEvent event) {
logger.info("Destroying Context...");
try {
WebApplicationContext context = (WebApplicationContext) event.getServletContext().getAttribute(
WebApplicationContext.root_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
Enumeration
while(attributes.hasMoreElements())
{
String attr = attributes.nextElement();
Object prop = event.getServletContext().getAttribute(attr);
logger.info("attribute.name: {},class:{}, value:{}",attr,prop.getClass().getName(),prop);
}
String[] beanNames = context.getBeanDefinitionNames();
for(String beanName:beanNames)
{
Object bean = context.getBean(beanName);
logger.info("found bean attribute in ServletContext,name:{},class:{},value:{}",
beanName,bean.getClass().getName(),bean);
if(beanName.contains("quartz")&&beanName.contains("Scheduler")){
StdScheduler scheduler = (StdScheduler)context.getBean("org.springframework.scheduling.quartz.SchedulerFactoryBean#0");
logger.info("发现quartz定时任务");
logger.info("beanName:{},className:{}",scheduler,scheduler.getClass().getName());
if(scheduler.isStarted())
{
logger.info("Quartz:waiting for job complete...");
scheduler.shutdown(true);
logger.info("Quartz:all threads are complete and exited...");
}
}
}
} catch (Exception e) {
logger.error("Error Destroying Context", e);
}
}
//https://stackoverflow.com/questions/23936162/register-shutdownhook-in-web-application
public void contextInitialized(ServletContextEvent event) {
//ServletContext context = event.getServletContext();
//System.setProperty("rootPath", context.getRealPath("/"));
//LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
//ctx.reconfigure();
/*logger.info("global setting,rootPath:{}",rootPath);
logger.info("deployed on architecture:{},operation System:{},version:{}",
System.getProperty("os.arch"), System.getProperty("os.name"),
System.getProperty("os.version"));
Debugger.dump();
logger.info("app startup completed....");*/
}
|
关闭tomcat日志如下:
其他解决方法
Shttp://pring配置文件
笔者经过实践,发现在spring配置文件里设置参数也可以达到以上效果
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~