user1535271
user1535271

Reputation: 149

ExecutorService java possible thread leak

I'm trying to run this simple class and for each cicle, I'm counting the number of java process threads.

ps huH p pid | wc -l.

I'm testion on centOS 6.5 with oracle java version 1.8.0_20.

For each cicle the number of threads is increasing of the number of availableProcessors().

It seems that garbace collector doesn't deallocate zombie threads when ExecutorService is running inside an other thread.

If I create a static ExecutorService it does not happend

private static final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());).

import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class ExecutorTest implements Runnable{

private ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private static final int CICLE_NUMBERS=100;
private static final int WAIT_SECONDS=20;

@Override
public void run() {
    try{
    ArrayList<Future<DummyThread>> responses = new ArrayList<>();
    for(int i=0;i<CICLE_NUMBERS;i++)
        responses.add((Future<DummyThread>) executor.submit(new DummyThread()));
    for (Future<DummyThread> future : responses)
        future.get(WAIT_SECONDS, TimeUnit.SECONDS);
    }
    catch(Exception e){
        e.printStackTrace();
    }
    System.gc();
}

public static void main(String[] args) throws InterruptedException {
    for(;;){
        new Thread(new ExecutorTest()).start();
        Thread.sleep(2000);
    }
}
}

class DummyThread implements Runnable{

@Override
public void run() {
    System.out.println("Hello World!");
}

}

Upvotes: 3

Views: 4168

Answers (2)

acearch
acearch

Reputation: 342

If you go through the code properly the reason that you are getting multiple pool objects is because of the statement

new Thread(new ExecutorTest()).start();

Every execution in the for loop is going to create a new instance of ExecutorService since it is a member variable of class ExecutorTest. Your program will keep running even without shutdown and since the threads will not be GCed since they are alive and working till the pools are shutdown.

If you make this a static variable then there is only one ExecutorService object within class level and that is why you do not get multiple pool objects created so you better not shutdown the pool else you will get an exception.

Upvotes: 0

jtahlborn
jtahlborn

Reputation: 53674

add a try/finally block inside your run() method and call shutdownNow() on the executor in the finally block.

Upvotes: 1

Related Questions