harry
harry

Reputation: 310

spring threadpooltaskexecutor causes memory leak in tomcat

I know this question was asked couple of times but none have provided a correct answer so reposting

I have a Spring4-Jersey webservice that runs inside Tomcat 7.

I am using Spring's ThreadPoolTaskExecutor to process some messages off a queue. I have a bean that uses @Scheduled which submits tasks to the executor every 1000 millis.

However, I have noticed when I shutdown Tomcat, it warns me that it can't shutdown some tasks.

    SEVERE: The web application appears to have started a thread named [taskExecutor-9] but has failed to stop it. This is very likely to create a memory leak.
 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

this what I have in code to initialize taskExecutor

@Bean(destroyMethod="shutdown")
 public Executor taskExecutor() {
     return Executors.newScheduledThreadPool(100);
 }

http://docs.spring.io/spring/docs/3.2.0.RC1_to_3.2.0.RC2/changes/docdiffs_org.springframework.scheduling.annotation.html

mentions that spring would take care of the threads that i created; but unfortunately it doesn't seem to be case...

Could someone provide any pointers ??

Upvotes: 0

Views: 3047

Answers (1)

Rajkishan Swami
Rajkishan Swami

Reputation: 3759

As its a web-application, you can try something like below;

Your SchedulingConfiguration Class

@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {

    /* Beans and Other Stuff */

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(workers());
    }

    @Bean(name = "executorService")
    ExecutorService workers() {
        return Executors.newScheduledThreadPool(100);
    }

}

ShutDown The ExecutorService in ServletContextListener's contextDestroyed method.

@Configuration
public class CustomServletContextListener implements ServletContextListener {

    @Autowired
    private ExecutorService executorService;

    @Override
    public void contextInitialized(ServletContextEvent context) {
        /* Do stuff If Required */
    }

    @Override
    public void contextDestroyed(ServletContextEvent context) {
        executorService.shutdown();
    }

}

Worked for me and I use Tomcat8.

Upvotes: 1

Related Questions