我在我的项目中使用石英.我的Web应用程序在停止时显然导致内存泄漏,错误是:
SEVERE: A web application appears to have started a TimerThread named [Timer-12] via the java.util.Timer API but has Failed to stop it. To prevent a memory leak,the timer (and hence the associated thread) has been forcibly cancelled. Jan 2,2013 6:55:35 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: A web application appears to have started a thread named [DefaultQuartzScheduler_Worker-1] but has Failed to stop it. This is very likely to create a memory leak.
我使用了org.quartz.ee.servlet.QuartzInitializerServlet和org.quartz.ee.servlet.QuartzInitializerListener.我厂的代码是:
StdSchedulerFactory factory = (StdSchedulerFactory) context.getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY );
而web.xml中的石英设置是:
<servlet> <servlet-name> QuartzInitializer </servlet-name> <display-name> Quartz Initializer Servlet </display-name> <servlet-class> org.quartz.ee.servlet.QuartzInitializerServlet </servlet-class> <load-on-startup> 1 </load-on-startup> <init-param> <param-name>shutdown-on-unload</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>wait-on-shutdown</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>start-scheduler-on-load</param-name> <param-value>true</param-value> </init-param> </servlet> <context-param> <param-name>quartz:shutdown-on-unload</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>quartz:wait-on-shutdown</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>quartz:start-on-load</param-name> <param-value>true</param-value> </context-param> <listener> <listener-class> org.quartz.ee.servlet.QuartzInitializerListener </listener-class> </listener>
请帮我解决这个内存泄漏!
解决方法
通过实现
org.quartz.InterruptableJob
,您可以正确地中断由servlet卸载触发的线程.
@DisallowConcurrentExecution public class Job implements InterruptableJob { private Thread thread; @Override public void execute(JobExecutionContext context) throws JobExecutionException { thread = Thread.currentThread(); // ... do work } @Override public void interrupt() throws UnableToInterruptJobException { thread.interrupt(); try { thread.join(); } catch (InterruptedException e) { throw new UnableToInterruptJobException(e); } finally { // ... do cleanup } } }
此示例可能会导致线程变量发生竞争状况错误,如果该作业在中断之前尚未执行.根据目标应用程序的生命周期,我将最终解决方案打开.如果需要通过相同的作业实例并发执行,请增加解决方案来处理多个线程并删除@DisallowConcurrentExecution
注释.
为了使这个工作,石英属性org.quartz.scheduler.interruptJobsOnShutdownWithWait必须设置为true.这可以通过为调度程序定义属性文件,或者通过使用spring框架的bean引用来完成.
示例quartz.properties文件:
org.quartz.scheduler.interruptJobsOnShutdownWithWait=true
请注意,如果调度程序配置为等待关闭,则仅调度中断,从而调用scheduler.shutdown(true)
.