Let\'s assume we have the following code:
List> runningTasks;
ExecutorService executor;
...
void executeTask(Runnable task){
runningTas
Until when the executor or the Future
object holds a reference to it is an implementation detail. Therefore, if your tasks use a lot of memory such that you have to worry about memory usage, you should explicitly clean up in your task before the task completes.
If you look at OpenJDK 1.6 source code of ThreadPoolExecutor
, you can see that in fact the underlying Future
object actually retains a reference to the underlying callable object indefinitely (i.e. as long as there is a strong reference to the Future
object, the callable cannot be GCd). This is true for 1.7 as well. As of 1.8, the reference to it is nulled out. However, you can't control on which implementation of ExecutorService
your task will run.
Using a WeakReference
should work in practice as the Future
and thus the Callable
object can be GCd once the task is done and sane implementations of ExecutorService
should lose reference to it when the task is done. Strictly speaking this still depends on the implementation of the ExecutorService though. Moreover, use of WeakReference can add surprisingly large overhead. You are much better off simply explicitly cleaning up whatever object that's taking up a lot of memory. Conversely, if you aren't allocating large objects then I wouldn't worry.
Of course this discussion is entirely different from the memory leak you'll have if you keep adding futures to your list without ever removing any. If you do this even using WeakReference
wouldn't help; you'll still have a memory leak. For this, simply iterate through the list and remove futures that are already done and thus are of no use. It's really fine to do this every time unless you have a ridiculously large queue size as this is very quick.
Future
.If you use ScheduledFuture
then you may face memory leak issue as ScheduledFuture.cancel()
or Future.cancel()
in general does not notify its Executor
that it has been cancelled and it stays in the Queue until its time for execution has arrived. It's not a big deal for simple Futures but can be a big problem for ScheduledFutures
. It can stay there for seconds, minutes, hours, days, weeks, years or almost indefinitely depending on the delays it has been scheduled with.
For more details with example of memory leak situation and its solution see my other answer.