I am writing some code where I might need to create an unbounded number of future objects (java.util.concurrent.Future).
But I am worried about running out of memory at some point.
Couple of questions here:
- Does the jvm know that once the future has completed, it is not being refernced anywhere and therefore is eligible for GC (even if the thread within which it was created is still alive and running)?
- Ideally, I wouldn't want to keep track of these futures themselves. But if I do keep the reference of these futures and periodically call cancel on them, will that make them available for GC?
You'll need to eventually remove any references to the Future
s in order for them to be garbage collected. The usual practice is to maintain a collection of the Future
s and periodically check whether isDone()
returns true
. If so, the task has completed and references to it may be cleaned up. If you are worried about piling up some long-running tasks which may be safely interrupted, you need to both call cancel()
on the Future
and remove/null out any references to it which may exist.
In general, it is always a bad idea to architect a system which can potentially experience unbounded growth. If the number of outstanding Future
objects grows too large, you should apply back pressure elsewhere in the system.
It is not necessarily the case that "once the future has completed, it is not being referenced anywhere." For example, a client with reference to it could request the result via the get()
method at any point. The JVM therefore needs to keep the Future
live until all these external references have been removed. The references within the thread pool will be removed when the Future
is "done" (meaning either it completed its task or was cancelled).
Have you seen this question?
Once the computation of a Future is complete, you cannot cancel it anymore.
I don't know the exact context, but one suggestion would be to keep track of the futures, cancel the ones you want or need to cancel and call purge on the executor to remove them from the working queue.
Hope it helps.