Reputation: 1073
I'm wondering the lifetime of Future
object, which is not bound to a named variable.
I learned that Java adopts mark & sweep style garbage collection.
In that case, any un-named object can be immediately deleted from heap. So I'm wondering if the Future
might be swept out from memory even before the Runnable
completes, or the memory might never be released.
Any information would be helpful, thanks!
class Main {
void main() {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> { return true; }); // not bind to variable
Thread.sleep(1000);
}
}
Upvotes: 1
Views: 415
Reputation: 718826
I learned that Java adopts mark & sweep style garbage collection.
That is mostly incorrect. Most modern Java garbage collectors are NOT mark & sweep. They are mostly copying collectors that work by evacuating (copying) objects to a "to" space as they are marked. And most Java garbage collectors are also generational.
There is a lot of material published by Oracle about the Java garbage collectors and how they work. And there a good textbooks on the subject too.
In that case, any un-named object can be immediately deleted from heap.
Names have nothing to do with it. References are not names, and neither are variables. Java objects are deleted by the GC only if it finds that they are unreachable; i.e. if no code will never be able to find them again1. Furthermore they are not deleted immediately, or even (necessarily) at the next GC run.
So I'm wondering if the
Future
might be swept out from memory even before theRunnable
completes, or the memory might never be released.
(That's a Callable
rather than a Runnable
. A Runnable
doesn't return anything.)
The answer is no it won't.
The life cycle is something like this:
submit
passing a Callable
.CompletableFuture
is created.CompletableFuture
and the Callable
are added to the executor's queue.CompletableFuture
is returned to the caller. (In your case, the caller throws it away.)Future
and the Callable
from the queue, executes the Callable
.complete
on the Future
to provide the result.Future.get
to obtain the result. (But not in your example.)In order for the step 6. to work, the CompletableFuture
must still be reachable. It won't be thrown away until all references are lost or discarded. Certainly not until after step 6 has completed.
Bottom line: a Java handles the Future
just like it would any other (normal) object. Don't worry about it. If anything needs it, it won't disappear.
1 - Reachability is a bit more complicated when you consider, finalization and Reference
types. But the same general principal applies. If any code could still see an object, it won't be deleted.
Upvotes: 2
Reputation: 159106
"Submit" means to give something to someone, in this case you're giving a piece of code (in the form of a Callable
) to the ExecutorService
for later execution. In return, the method returns a Future
object that will be updated with the result when it is done.
In order for the ExecutorService
to update the Future
object, it needs to hold on the Future
object too, together with the code reference (the Callable
).
Therefore, the ExecutorService
maintains references to both the Callable
object and the Future
object until the job has been completed. Those references makes both objects reachable, preventing the objects from being garbage-collected.
Since your code discarded the returned Future
object, the object will become eligible for GC as soon as the job completes, but not before that.
Upvotes: 1