时间:2021-05-20
这篇文章主要介绍了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;@WebListenerpublic 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<String> attributes = event.getServletContext().getAttributeNames(); 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(); }|关闭tomcat日志如下:
其他解决方法
Spring配置文件
笔者经过实践,发现在spring配置文件里设置参数也可以达到以上效果
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="simpleTrigger" /> <ref bean="cronTrigger" /> <ref bean="secondCronTrigger"/> </list> </property> <property name="waitForJobsToCompleteOnShutdown" value="true"/> </bean><property name="waitForJobsToCompleteOnShutdown" value="true"/>可以在web关闭的时候关闭线程
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
Get中文乱码问题解决方案:修改Tomcat根目录下conf/server.xml文件,代码如下:复制代码代码如下:但是,使用IE浏览器会发现,中文乱码问题仍然
先看解决方案#------------mysqlroot用户无法赋权问题解决--------1,登录mysql-uroot-p2,usemysql;选择mysq
pythonsocket.error:[Errno10054]远程主机强迫关闭了一个现有的连接。问题解决方案:前几天使用python读取网页。因为对一个网站大量
问题:使用keep-alive标签后部分安卓机返回缓存页位置不精确问题解决方案:constrouter=newRouter({scrollBehavior(to
一、概述在Android内存泄漏终极解决篇(上)中我们介绍了如何检查一个App是否存在内存泄漏的问题,本篇将总结典型的内存泄漏的代码,并给出对应的解决方案。内存