Spring3. 2. 1 1 with Quartz2. 2. 1 integrated memory leaks problem solving-vulnerability warning-the black bar safety net

2015-07-05T00:00:00
ID MYHACK58:62201564342
Type myhack58
Reporter 佚名
Modified 2015-07-05T00:00:00

Description

Quartz is a timer task scheduling open-source framework, use up more convenient. And Spring's support package for Quartz with integrated. But the author in the web application using the process but encountered a memory leak problem. Problems of the author in using the Spring+Quartz usage is as follows, familiar with Spring+Quartz you can skip directly to see the problem: 1.The Configure Scheduler factory 2. Prepare Job implementation class QuartzJob, is used to perform the task//here must inherit the spring of the QuartzJobBeanpublic class QuartzJob extends QuartzJobBean {/ * task execution of the content. / @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { // execute the code }}3. The Scheduler plant production scheduler is injected into the business logic class. Note here that the injection is actually by schedulerFactory out of production scheduler instance the Spring is not familiar with people will naturally think that the injection is the schedulerFactory instance, this is because the Spring's SchedulerFactoryBean implements FactoryBean interface, so the injection results will be FactoryBean. getObject()get the instance of the digression in. public class TaskServiceImpl { private Scheduler scheduler;/ * by the spring through the factory injection, and this instance is a single example. * @param scheduler */ public void setScheduler(Scheduler scheduler) { this. scheduler = scheduler; }4. In the business logic class TaskServiceImpl, use the scheduler to perform the task. Here you can live on the task to perform add, delete, restart, etc. operations. Another important characteristic is that you can dynamically change the Cron expression of task the timing of the rule change. 1 /2 * The new tasks. 3 * @param jobName4 * @param jobGroup5 * @param cron6 */7 public void addJob(String jobName, String jobGroup, String cron, String kindId) {8 try {9 if (StringUtil. isEmpty(jobName) || StringUtil. isEmpty(jobGroup) || StringUtil. isEmpty(cron)) {1 0 throw new BusinessException("timer task creation failed, the parameter is empty");1 1 }1 2 JobDetail jobDetail = JobBuilder. newJob(QuartzJob.class). withIdentity(jobName, jobGroup). build();1 3 jobDetail. getJobDataMap(). put("JobKind", kindId);1 4 //expression schedule Builder 1 5 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder. cronSchedule(cron);1 6 //according to the new cronExpression the expression to build a new trigger17 CronTrigger trigger = TriggerBuilder. newTrigger(). withIdentity(jobName, jobGroup). withSchedule(scheduleBuilder). build();1 8 scheduler. scheduleJob(jobDetail, trigger);1 9 log("add new scheduled task, name:" + jobName + ",group:" + jobGroup + ",cron:" + cron);2 0 } catch (SchedulerException e) {2 1 // for exception handling 2 2 }2 3 }Note 1 8-row scheduler by Spring injection. This usage is in the use of the process no problem, but in a web application in Tomcat6 in hot deployment when the accident happens the following serious warning, if you ignore this warning, in the Frequent reload will cause Tomcat Permgen space OOM in. Jun 2 4, 2 0 1 4 5:1 4:3 8 AM the org. apache. the catalina. loader. WebappClassLoader clearReferencesThreadsSEVERE: 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 2 4, 2 0 1 4 5:1 4:3 8 AM the org. apache. the catalina. loader. WebappClassLoader clearReferencesThreadsSEVERE: 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 2 4, 2 0 1 4 5:1 4:3 8 AM the org. apache. the catalina. loader. WebappClassLoader clearReferencesThreadsSEVERE: 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 2 4, 2 0 1 4 5:1 4:3 8 AM the org. apache. the catalina. loader. WebappClassLoader clearReferencesThreadsSEVERE: 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 2 4, 2 0 1 4 5:1 4:3 8 AM the org. apache. the catalina. loader. WebappClassLoader clearReferencesThreadsSEVERE: 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 2 4, 2 0 1 4 5:1 4:3 8 AM the org. apache. the catalina. loader. WebappClassLoader clearReferencesThreadsSEVERE: 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 2 4, 2 0 1 4 5:1 4:3 8 AM the org. apache. the catalina. loader. WebappClassLoader clearReferencesThreads the cause of the problem the reason is the open scheduler_Worker thread is not closed. But Spring's SchedulerFactoryBean implements the DisposableBean interface that represents the web container closed when executing destroy (), the execution content below: / * * Shut down the Quartz scheduler on bean factory shutdown, * stopping all scheduled jobs. / public void destroy() throws SchedulerException { logger("Shutting down Quartz Scheduler"); this. scheduler. shutdown(this. waitForJobsToCompleteOnShutdown); }represents the factory has done a shutdown on. So, the problem occurs in the real execution of the scheduler. shutdown(true). It turns out that this is a Quartz bug, in the call scheduler. shutdown(true)after the Quartz check thread and does not wait for those workerThread is stopped on the end. Online that in Quartz2. 1 versions have patched this bug, but the author used the 2. 2. 1 version there are still problems. To solve the problem then the problem how to solve, here are a not too beautiful solution: in the call scheduler. shutdown(true)after adding a little sleep time, waiting for the worker thread to stop all that. As follows: 1. The Custom schedulerFactory inherits Spring's SchedulerFactoryBean and override destroy()to increase delay. public class SchedulerFactoryBeanWithShutdowndelay extends SchedulerFactoryBean { / * about Quartz memory leak is not too aesthetically pleasing solution: * in the call scheduler. shutdown(true)after increasing the delay, waiting for the worker thread ends. / @Override public void destroy() throws SchedulerException { super. destroy(); try { Thread. sleep(1 0 0 0); } catch (InterruptedException e) { throw new RuntimeException(e); } }}2。 The spring configuration file in the SchedulerFactoryBean replaced with a custom factory can be. OK, problem solved.