Java – how to prevent memory leaks
I use quartz in my project My web application apparently caused a memory leak when it stopped. The error is:
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.
I used org quartz. ee. servlet. Quartzinitializerservlet and org quartz. ee. servlet. QuartzInitializerListener. The code of our factory is:
StdSchedulerFactory factory = (StdSchedulerFactory) context.getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY );
And web The settings in XML are:
<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>
Please help me solve this memory leak!
Solution
By implementing org quartz. Interruptible job, you can correctly interrupt the thread triggered by servlet unloading
@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
}
}
}
This example may cause race errors in thread variables if the job has not been executed before the interrupt According to the life cycle of the target application, I open the final solution If you need to execute concurrently through the same job instance, please add a solution to handle multiple threads and delete the @ disallowcurrentexecution annotation
To make this work, quartz properties org quartz. scheduler. Interruptjobsonshutdown withwait must be set to true This can be done by defining a properties file for the scheduler or by using the bean reference of the spring framework
Example quartz Properties file:
org.quartz.scheduler.interruptJobsOnShutdownWithWait=true
Note that if the scheduler is configured to wait for shutdown, only interrupts are scheduled, calling scheduler shutdown(true).
