Spring整合quartz关闭,关闭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<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配置文件
笔者经过实践,发现在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关闭的时候关闭线程
Spring整合quartz关闭,关闭Tomcat Servlet容器时内存泄漏的更多相关文章
- 初识quartz 并分析 项目中spring整合quartz的配置【原创+转载】
初识quartz 并分析 项目中spring整合quartz的配置[原创+转载]2018年01月29日 12:08:07 守望dfdfdf 阅读数:114 标签: quartz 更多个人分类: 工具 ...
- spring整合quartz并持久化
spring整合quartz有两种方式: 一.常见是使用配置文件,将定时任务保存到内存中 简单示例: <!-- 短信催还提醒任务调度 --> <bean id="overd ...
- Spring整合Quartz定时任务执行2次,Spring定时任务执行2次
Spring整合Quartz定时任务执行2次,Spring定时任务执行2次 >>>>>>>>>>>>>>>&g ...
- spring整合quartz框架
spring整合quartz: 网上也有很多教程,好多都是基于配置方式,我们使用当然怎么简单就怎么用,所以这里介绍基于注解方式整合quartz.前提:你需要有一个能运行的web项目. 1.引依赖: & ...
- 使用Spring整合Quartz轻松完成定时任务
一.背景 上次我们介绍了如何使用Spring Task进行完成定时任务的编写,这次我们使用Spring整合Quartz的方式来再一次实现定时任务的开发,以下奉上开发步骤及注意事项等. 二.开发环境及必 ...
- spring整合quartz时间任务调度框架
spring整合quartz框架 1.创建maven工程 2.导入jar包(pom.xml) <dependencies> <dependency> <groupId&g ...
- Spring整合Quartz定时任务 在集群、分布式系统中的应用(Mysql数据库环境)
Spring整合Quartz定时任务 在集群.分布式系统中的应用(Mysql数据库环境) 转载:http://www.cnblogs.com/jiafuwei/p/6145280.html 单个Q ...
- Spring quartz Job不能依赖注入,Spring整合quartz Job任务不能注入
Spring quartz Job不能依赖注入,Spring整合quartz Job任务不能注入 Spring4整合quartz2.2.3中Job任务使用@Autowired不能注入 >> ...
- 使用spring整合Quartz实现—定时器
使用spring整合Quartz实现—定时器(Maven项目做演示) 不基于特定的基类的方法 一,开发环境以及依赖的jar包 Spring 4.2.6.RELEASE Maven 3.3.9 Jdk ...
随机推荐
- REST API TO MiniProgram 上线WordPress官方插件库
全新开发的用于 wordpress微信小程序的插件 REST API TO MiniProgram今天上线WordPress官方插件库.这个插件的上一个版本叫:wp-rest-api-for-app, ...
- CSS画三角形图标
/* 等腰三角形(箭头朝上): */ #div1{ width: 0; height: 0; border-bottom: 100px solid cyan; border-left: 50px so ...
- leetcode《按递增顺序显示卡牌》
题目描述: 牌组中的每张卡牌都对应有一个唯一的整数.你可以按你想要的顺序对这套卡片进行排序. 最初,这些卡牌在牌组里是正面朝下的(即,未显示状态). 现在,重复执行以下步骤,直到显示所有卡牌为止: 从 ...
- jQuery 正则数字验证、’Money验证、电话号码验证、身份证验证、邮箱验证、网址验证、敏感字符验证
jQuery只能输入数字 第一种写法: <input onkeyup="value=value.replace(/[^\d]/g,'')" /> 第二种写法: < ...
- 微信公众号openid处理的一些笔记
每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同.如果公司有多个公众号,可以通过开放平台关联,这样同一用户,对同一个微信开放平台下的不同应用,unionid是相同 ...
- OO第一单元(求导)单元总结
OO第一单元(求导)单元总结 这是我们oo课程的第一个单元,也是意在让我们接触了解掌握oo思想的一个单元,这个单元的作业以求导为主题,从一开始的加减多项式求导再到最后的嵌套多项式求导,难度逐渐提高,编 ...
- azkaban工作流调度器及相关工具对比
本文转载自:工作流调度器azkaban,主要用于架构选型,安装请参考:Azkaban安装与简介,azkaban的简单使用 为什么需要工作流调度系统 一个完整的数据分析系统通常都是由大量任务单元组成: ...
- Python paramiko模块基本使用(一)
使用paramiko模块登录远程主机,对日志进行统计分析. import paramiko def batch_count(days, hours, ips, user, passwd, source ...
- C++文档补充
string s("100010"); bitset<5> b(s,2,2); 只有上图这样写,下图这样是错的.记住.http://www.cppblog.com/k ...
- django的内置分页
本节内容 自定义一个简单的内置分页 Django内置分页 Django内置分页扩展(继承) 自定义内置组件 自定义一个简单的内置分页 先用django自己自定制一个简单的内置分页,大概掌握内置分页的底 ...