为什么这个线程池没有垃圾收集? [英] Why doesn't this thread pool get garbage collected?

查看:152
本文介绍了为什么这个线程池没有垃圾收集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此代码示例中,ExecutorService使用一个,并允许超出范围。

In this code example, the ExecutorService is used one and allowed to go out of scope.

public static void main(String[] args)
{
    ExecutorService executorService = Executors.newFixedThreadPool(3);
    executorService.submit(new Runnable()
    {
        public void run()
        {
            System.out.println("hello");
        }
    });
}

一旦executorService超出范围,应收集并完成。 ThreadPoolExecutor中的finalize()方法调用shutdown()。

Once executorService is out of scope, it should get collected and finalized. The finalize() method in ThreadPoolExecutor calls shutdown().

/**
 * Invokes {@code shutdown} when this executor is no longer
 * referenced and it has no threads.
 */
protected void finalize() {
    shutdown();
}

一旦shutdown()被调用,池线程应该终止,被允许退出。但是executorSerivce从来没有被收集,因此JVM仍然活着。甚至调用System.gc()似乎没有工作。为什么即使在main()终止后也不会收集executorService?

Once shutdown() is called, the pool threads should terminate and the JVM should be allowed to exit. However the executorSerivce is never getting collected and thus the JVM stays alive. Even calls to System.gc() don't seem to work. Why isn't executorService getting collected even after main() terminates?

注意:我知道我应该调用shutdown()我很好奇为什么finalization不能作为一个备份在这里。

Note: I know I should call shutdown() myself and I always do outside of testing. I'm curious why finalization isn't working as a back-up here.

推荐答案

这真的没有什么做GC是非确定性的,虽然它不帮助! (这是你的例子中的一个原因,但即使我们'固定'它来消耗内存和强制收集,它仍然不会最终确定)

This doesn't really have anything to do with GC being non-deterministic, although it doesn't help! (That is one cause in your example, but even if we 'fixed' it to eat up memory and force a collection, it still wouldn't finalize)

执行器创建的线程是内部类,它具有返回执行器本身的引用。 (他们需要它能够看到队列,runstate等!)运行线程不是垃圾收集,所以在池中的每个线程都有这个引用,他们将保持执行器活着,直到所有线程都死了。如果你不手动做某事停止线程,他们将永远运行,你的JVM永远不会关闭。

The Worker threads that the executor creates are inner classes that have a reference back to the executor itself. (They need it to be able to see the queue, runstate, etc!) Running threads are not garbage collected, so with each Thread in the pool having that reference, they will keep the executor alive until all threads are dead. If you don't manually do something to stop the threads, they will keep running forever and your JVM will never shut down.

这篇关于为什么这个线程池没有垃圾收集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆