Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring + Quartz = Memory Leaks

I use the following libraries.

  • quartz-2.2.1
  • spring-webmvc-3.2.9.RELEASE

on Apache Tomcat/7.0.52 (Ubuntu).

I use Spring to configure 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;
    }
}

Searched a lot today why the scheduler tasks where not shut down correctly...

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.

The ugly hack was to write the SchedulerFactoryBeanWithShutdownDelay class.

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);
        }
    }
}

But this issue should have been closed: https://jira.terracotta.org/jira/browse/QTZ-192

Have I made a mistake or can this be confirmed?

like image 648
Nabor Avatar asked Jun 24 '14 13:06

Nabor


People also ask

What is the main cause of memory leaks?

DEFINITION A memory leak is the gradual deterioration of system performance that occurs over time as the result of the fragmentation of a computer's RAM due to poorly designed or programmed applications that fail to free up memory segments when they are no longer needed.

How do you detect memory leaks?

The primary tools for detecting memory leaks are the C/C++ debugger and the C Run-time Library (CRT) debug heap functions. The #define statement maps a base version of the CRT heap functions to the corresponding debug version. If you leave out the #define statement, the memory leak dump will be less detailed.


1 Answers

An excellent article on memory leaks in Tomcat. Read the article, start your web app, let Quartz jobs execute, then stop the web app, then take a heap dump of Tomcat's JVM, load the heap dump into Eclipse MAT and find out which classes cause memory leaks. Then you should be able to fix the issue.

like image 157
Sergey Grigoriev Avatar answered Oct 06 '22 17:10

Sergey Grigoriev