【发布时间】:2014-06-24 13:11:53
【问题描述】:
我使用以下库。
- quartz-2.2.1
- spring-webmvc-3.2.9.RELEASE
在 Apache Tomcat/7.0.52 (Ubuntu) 上。
我使用 Spring 来配置 Quartz。
@Configuration
class QuartzConfig {
@Bean
FactoryBean<Scheduler> scheduler() {
final SchedulerFactoryBean factory = new SchedulerFactoryBeanWithShutdownDelay();
final Map<String, Object> map = new LinkedHashMap<>();
map.put("settingsService", settingsService);
final List<AbstractQuartzJob> jobs = new LinkedList<>();
jobs.add(dbBackupJob());
jobs.add(csvExportJob());
jobs.add(csvImportJob());
jobs.add(dbMaintenanceJob());
jobs.add(filesystemCleanupJob());
map.put("jobs", jobs);
factory.setSchedulerContextAsMap(map);
factory.setTriggers(new Trigger[] {cronTrigger});
return factory;
}
}
今天搜索了很多为什么调度程序任务没有正确关闭...
Jun 24, 2014 5:14:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/feeder##1.5.0] appears to have started a thread named [scheduler_Worker-1] but has failed to stop it. This is very likely to create a memory leak.
Jun 24, 2014 5:14:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/feeder##1.5.0] appears to have started a thread named [scheduler_Worker-2] but has failed to stop it. This is very likely to create a memory leak.
Jun 24, 2014 5:14:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/feeder##1.5.0] appears to have started a thread named [scheduler_Worker-3] but has failed to stop it. This is very likely to create a memory leak.
Jun 24, 2014 5:14:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/feeder##1.5.0] appears to have started a thread named [scheduler_Worker-4] but has failed to stop it. This is very likely to create a memory leak.
Jun 24, 2014 5:14:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/feeder##1.5.0] appears to have started a thread named [scheduler_Worker-5] but has failed to stop it. This is very likely to create a memory leak.
Jun 24, 2014 5:14:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/feeder##1.5.0] appears to have started a thread named [scheduler_Worker-6] but has failed to stop it. This is very likely to create a memory leak.
Jun 24, 2014 5:14:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/feeder##1.5.0] appears to have started a thread named [scheduler_Worker-7] but has failed to stop it. This is very likely to create a memory leak.
Jun 24, 2014 5:14:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/feeder##1.5.0] appears to have started a thread named [scheduler_Worker-8] but has failed to stop it. This is very likely to create a memory leak.
Jun 24, 2014 5:14:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/feeder##1.5.0] appears to have started a thread named [scheduler_Worker-9] but has failed to stop it. This is very likely to create a memory leak.
Jun 24, 2014 5:14:38 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/feeder##1.5.0] appears to have started a thread named [scheduler_Worker-10] but has failed to stop it. This is very likely to create a memory leak.
丑陋的 hack 是编写 SchedulerFactoryBeanWithShutdownDelay 类。
public class SchedulerFactoryBeanWithShutdownDelay extends SchedulerFactoryBean {
private static final int SHUTDOWN_TIMEOUT = 2000;
@Override
public void destroy() throws SchedulerException {
log.debug("Start shutdown of Quartz scheduler factory bean");
super.destroy();
try {
log.debug("wait {}ms to shutdown Quartz", SHUTDOWN_TIMEOUT);
Thread.sleep(SHUTDOWN_TIMEOUT);
log.debug("Quartz scheduler shutdown completed");
} catch (InterruptedException e) {
log.error("", e);
}
}
}
但是这个issue应该已经关闭了:https://jira.terracotta.org/jira/browse/QTZ-192
是我犯了错误还是可以确认?
【问题讨论】:
-
只是出于好奇,既然 Spring 有自己的内置调度程序,为什么还要使用 quarts?
-
为什么不呢?可能是历史原因。自从我们开始项目以来就使用它并且工作得很好,除了停止或重新启动 Web 应用程序期间出现的问题,这对我们来说不是问题。
-
您是否真的有内存泄漏,或者您只是被日志文件中的消息带走了?另请注意,spring 默认调用
scheduler.shutdown(false),因为问题提到了scheduler.shutdown(true)。要启用后者,请将SchedulerFactoryBean上的waitForJobsToCompleteOnShutdown属性设置为true。 -
是的,我们实际上在我们的机器上看到了内存泄漏。这就是为什么给大家的建议是在部署 Feeder web 应用程序后重新启动 tomcat。如果不经常这样做,我们会看到 perm gen space 错误,然后需要重新启动 Tomcat。谢谢你>
scheduler.shutdown(true)我已经监督了这个。现在改了之后,日志里的问题就没有了……