Does an ExecutorService get garbage collected when out of scope?

后端 未结 2 1002
星月不相逢
星月不相逢 2021-01-01 15:04

I\'m asking this question because I am creating a lot of executor services and while I may already have a memory leak somewhere that needs to be investigated, I think a rece

相关标签:
2条回答
  • 2021-01-01 15:15

    Does the ExecutorService service go out of scope and get garbage collected once BaseConsumer.accept() has finished?

    Yes.

    Indeed, the associated thread pool should also be garbage collected ... eventually.

    The ExecutorService that is created by Executors.newSingleThreadExecutor() an instance of FinalizableDelegatedExecutorService. That class has finalize() method that calls shutdown() on the wrapped ExecutorService object. Provided that all outstanding tasks actually terminate, the service object will shut down its thread pool.

    (AFAIK, this is not specified. But it is what is implemented according to the source code, in Java 6 onwards.)


    Does adding a finally { service.shutdown(); } in the try-catch around future.get() help in retrieving resources quicker? (not necessarily garbage collecting the service object).

    Yes it does. Calling shutdown() causes the threads to be released as soon as the outstanding tasks complete. That procedure starts immediately, whereas if you just left it to the garbage collector it wouldn't start until the finalizer was called.

    Now if the resources were just "ordinary" Java objects, this wouldn't matter. But in this case, the resource that you are reclaiming is a Java thread, and that has associate operating system resources (e.g. a native thread), and a non-trivial chunk of out-of-heap memory. So it is maybe worthwhile to do this.

    But if you are looking to optimize this, maybe you should be creating a long-lived ExecutorService object, and sharing it across multiple "consumer" instances.

    0 讨论(0)
  • 2021-01-01 15:16

    I want to let the execution take place on a named thread, it has to do with it being easier to log. In either case, this code should work.

    You can do this much simpler/faster

    Thread t = Thread.currentThread();
    String name = t.getName();
    try {
        t.setName("My new thread name for this task");
        // do task
    } finally {
        t.setName(name);
    }
    

    This way you can use a named thread without creating a new one.

    0 讨论(0)
提交回复
热议问题