码迷,mamicode.com
首页 > 编程语言 > 详细

Spring整合quartz关闭,关闭Tomcat Servlet容器时内存泄漏

时间:2017-09-23 12:29:19      阅读:1061      评论:0      收藏:0      [点我收藏+]

标签:问题   ssi   img   ack   listen   top   内存泄漏   dep   and   

出错信息

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)
22-Sep-2017 06:19:51.065 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-2] 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)
22-Sep-2017 06:19:51.065 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-3] 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)
22-Sep-2017 06:19:51.068 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-4] 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)
22-Sep-2017 06:19:51.069 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-5] 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)
22-Sep-2017 06:19:51.070 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-6] 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)
22-Sep-2017 06:19:51.071 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-7] 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)
22-Sep-2017 06:19:51.072 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-8] 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)
22-Sep-2017 06:19:51.073 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-9] 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)
22-Sep-2017 06:19:51.080 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-10] 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)

问题分析: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<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();
          /*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日志如下:

技术分享

 

Spring整合quartz关闭,关闭Tomcat Servlet容器时内存泄漏

标签:问题   ssi   img   ack   listen   top   内存泄漏   dep   and   

原文地址:http://www.cnblogs.com/passedbylove/p/7580477.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!