ExecutorService在频繁关闭后导致内存不足异常

Thr*_*eaT 1 java concurrency multithreading executorservice

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ExecutorServiceTest {

    public static void main(String args[]) {
        new ExecutorServiceTest();
    }

    public ExecutorServiceTest() {
        while (true) {
            action();
        }
    }

    public String action() {
        String string = "";
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<String> future = executor.submit(new Callable() {
            @Override
            public String call() {
                return randomString();
            }
        });
        try {
            string = future.get(1, TimeUnit.MILLISECONDS);
        } catch (InterruptedException | ExecutionException | TimeoutException ex) {

        }
        future.cancel(true);
        executor.shutdownNow();
        return string;
    }

    public String randomString() {
        return "asdhkashdkjshakdasdsahdka";
    }

}
Run Code Online (Sandbox Code Playgroud)

如果打开任务管理器窗口然后运行此类,您会注意到Java立即使用了大量内存.我已经彻底搜索并调试了类,但找不到内存泄漏.

是什么导致future.get(1, TimeUnit.MILLISECONDS);耗尽所有系统内存然后崩溃?

Tag*_*eev 6

所述ThreadPoolExecutor类具有非空finalize()方法(其执行池关机),因此,当垃圾收集它首先进入终结队列(其基本上是链表),并通过单独的"终结"线程处理.即使池没有活动任务,关闭它也很慢.根据硬件,操作系统和运行条件的不同,新的终结器的添加速度可能比Finalizer线程处理的速度快,因此您可能期望内存不断增长.通常,您不应该过快地创建和关闭执行程序.