超出范围时,ExecutorService是否会收集垃圾?

我问这个问题是因为我正在创建很多执行程序服务,尽管我可能已经在某个地方进行内存泄漏了,需要进行调查,但是我认为对以下代码的最近更改实际上使它更糟,因此,我尝试确认到底是怎么回事:

@FunctionalInterface

public interface BaseConsumer extends Consumer<Path> {

@Override

default void accept(final Path path) {

String name = path.getFileName().toString();

ExecutorService service = Executors.newSingleThreadExecutor(runnable -> {

Thread thread = new Thread(runnable, "documentId=" + name);

thread.setDaemon(true);

return thread;

});

Future<?> future = service.submit(() -> {

baseAccept(path);

return null;

});

try {

future.get();

} catch (InterruptedException ex) {

Thread.currentThread().interrupt();

} catch (ExecutionException ex) {

throw new RuntimeException(ex);

}

}

void baseAccept(final Path path) throws Exception;

}

然后,这Consumer<Path>会在(通常)N = 2个线程的另一个线程池上被调用,我不确定这是否相关。

问题是:一旦完成,是否ExecutorService service超出范围 获取垃圾BaseConsumer#accept

回答:

ExecutorService服务是否超出范围并BaseConsumer.accept()在完成后获得垃圾回收?

是。

确实,关联的线程池也应该最终被垃圾回收。

ExecutorService由创建Executors.newSingleThreadExecutor()的实例FinalizableDelegatedExecutorService。该类具有finalize()调用shutdown()包装ExecutorService对象的方法。如果所有未完成的任务实际上终止,则服务对象将关闭其线程池。

(AFAIK,未指定。但这是根据源代码实现的,从Java 6开始。)


是否添加最后一个{service.shutdown(); }在future.get()的try-

catch中有助于更快地检索资源?(不一定是垃圾收集服务对象)。

是的,它确实。调用shutdown()导致线程在未完成的任务完成后立即释放。该过程将立即开始,而如果您将其留给垃圾收集器,则直到调用终结器才开始。

现在,如果资源只是“普通”

Java对象,那就没关系了。但是在这种情况下,您要回收的资源是Java线程,并且具有关联的操作系统资源(例如本机线程)和非平常的堆外内存块。因此,这样做可能值得。

但是,如果您要优化它,也许您应该创建一个寿命很长的ExecutorService对象,并在多个“消费者”实例之间共享它。

以上是 超出范围时,ExecutorService是否会收集垃圾? 的全部内容, 来源链接: utcz.com/qa/397475.html

回到顶部