ExecutorService java possible thread leak
I am trying to run this simple class and for each cicle, I am counting the number of java process threads.
ps huH p pid | wc -l .
I am testing centOS 6.5 with oracle java version 1.8.0_20 .
For each cicle, the number of threads increases by the number of available processors () .
It seems that the garment collector does not release zombie threads when the ExecutorService is running inside another thread.
If I create a static ExecutorService it doesn't happen
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!");
}
}
source to share
If you are looking at the code correctly, the reason you are getting multiple pool objects is due to the expression
new Thread(new ExecutorTest()).start();
Each execution of the for loop creates a new ExecutorService instance because it is a member variable of the ExecutorTest class. Your program will run even without shutdown, and the threads will not be GCed as they are alive and running until the pool is finished.
If you make it a static variable, that is, there is only one ExecutorService object within the class level, which is why you do not get multiple create pool objects, so you better not turn off the pool otherwise you will get an exception.
source to share