executorService.submit(Runnable)返回的将来对象是否持有对可运行对象的任何引用? [英] Does the future object returned by executorService.submit(Runnable) hold any reference to the runnable object?

查看:235
本文介绍了executorService.submit(Runnable)返回的将来对象是否持有对可运行对象的任何引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有以下代码:

List<Future<?>> runningTasks;
ExecutorService executor;
...
void executeTask(Runnable task){
    runningTasks.add(executor.submit(task));
}

我的问题是:

  1. runningTasks是否保存对task对象的引用?
  2. 将其保存多长时间?任务完成后,它还会保留它吗?
  3. 为了避免内存泄漏,我必须注意删除添加到列表中的将来吗?
  1. Does runningTasks hold a reference to the task object?
  2. How long does it hold it for? Does it still hold it after the task is complete?
  3. In order to avoid memory leaks do I have to take care to remove the future that was added to the list?

推荐答案

直到执行器或Future对象持有对其的引用是实现细节.因此,如果您的任务使用大量内存,因此您不得不担心内存使用情况,则应在任务完成之前明确清理任务.

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.

在实践中,使用WeakReference应该与Future一样工作,因此,一旦完成任务,就可以将Callable对象作为GCd了,并且ExecutorService的合理实现应该在完成任务后不再引用它.严格来说,这仍然取决于ExecutorService的实现.此外,使用WeakReference可能会增加惊人的开销.简单地显式清理占用大量内存的任何对象,您会变得更好.相反,如果您不分配大对象,那么我不会担心.

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.

当然,如果您不加删除任何期货就继续将期货添加到列表中,那么本次讨论将与内存泄漏完全不同.如果执行此操作,即使使用WeakReference也无济于事;您仍然会发生内存泄漏.为此,只需遍历列表并删除已经完成的期货,因此就没有用了.除非每次队列都大得离谱,否则每次都这样做是非常好的.

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.

这篇关于executorService.submit(Runnable)返回的将来对象是否持有对可运行对象的任何引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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