Spring關(guān)閉Tomcat Servlet容器時內(nèi)存泄漏問題解決方案
這篇文章主要介紹了Spring關(guān)閉Tomcat Servlet容器時內(nèi)存泄漏問題解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
出錯信息
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容器關(guān)閉時發(fā)現(xiàn)Quartz定時器線程還在執(zhí)行,對其無所適從,不懂怎么辦只能強行關(guān)閉。
解決思路
在關(guān)閉容器時的contextDestroyed事件里檢測ServletContext里Quartz相關(guān)屬性,找到Bean然后調(diào)用它的方法結(jié)束掉。
解決方法
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<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("發(fā)現(xiàn)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....");*/ } |
關(guān)閉tomcat日志如下:
其他解決方法
Spring配置文件
筆者經(jīng)過實踐,發(fā)現(xiàn)在spring配置文件里設置參數(shù)也可以達到以上效果
<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關(guān)閉的時候關(guān)閉線程
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- SpringMVC利用dropzone組件實現(xiàn)圖片上傳
- SpringMVC的執(zhí)行流程及組件詳解
- bootstrap fileinput組件整合Springmvc上傳圖片到本地磁盤
- SpringBoot注冊Servlet的三種方法詳解
- 詳解Spring框架下向異步線程傳遞HttpServletRequest參數(shù)的坑
- Servlet+MyBatis項目轉(zhuǎn)Spring Cloud微服務,多數(shù)據(jù)源配置修改建議
- Spring MVC學習之DispatcherServlet請求處理詳析
- SpringMVC DispatcherServlet組件實現(xiàn)解析
相關(guān)文章
mybatis-plus的SafetyEncryptProcessor安全加密處理示例解析
這篇文章主要為大家介紹了mybatis-plus的SafetyEncryptProcessor安全加密處理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08關(guān)于ZooKeeper的會話機制Session解讀
這篇文章主要介紹了關(guān)于ZooKeeper的會話機制Session解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02java求最大公約數(shù)與最小公倍數(shù)的方法示例
這篇文章主要介紹了java求最大公約數(shù)與最小公倍數(shù)的方法,涉及java數(shù)值運算的相關(guān)操作技巧,并附帶分析了eclipse環(huán)境下設置運行輸入?yún)?shù)的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11spring通過構(gòu)造函數(shù)注入實現(xiàn)方法分析
這篇文章主要介紹了spring通過構(gòu)造函數(shù)注入實現(xiàn)方法,結(jié)合實例形式分析了spring通過構(gòu)造函數(shù)注入的原理、實現(xiàn)步驟及相關(guān)操作注意事項,需要的朋友可以參考下2019-10-10Spring?BeanFactory容器的構(gòu)建和使用示例詳解
BeanFactory是Spring框架中的一部分,它提供了IoC(控制反轉(zhuǎn))的實現(xiàn)機制,下面小編就來和大家簡單聊聊BeanFactory容器的構(gòu)建和使用示例吧2023-07-07Java如何接收前端easyui?datagrid傳遞的數(shù)組參數(shù)
這篇文章分享一下怎么在easyui的datagrid刷新表格時,在后端java代碼中接收datagrid傳遞的數(shù)組參數(shù),本文通過實例代碼給大家介紹的非常詳細,需要的朋友參考下吧2023-11-11