gpt4 book ai didi

java - executorService.submit(Runnable) 返回的 future 对象是否包含对可运行对象的任何引用?

转载 作者:搜寻专家 更新时间:2023-10-30 21:34:56 25 4
gpt4 key购买 nike

假设我们有以下代码:

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

我的问题是:

  1. runningTasks 是否包含对 task 对象的引用?
  2. 它能保持多长时间?任务完成后它还持有吗?
  3. 为了避免内存泄漏,我是否必须小心删除添加到列表中的 future ?

最佳答案

直到执行者或 Future 对象持有对它的引用时是一个实现细节。因此,如果您的任务使用大量内存以至于您不得不担心内存使用,您应该在任务完成之前在任务中明确清理。

如果你看OpenJDK 1.6 source codeThreadPoolExecutor 中,您可以看到实际上底层 Future 对象实际上无限期地保留对底层可调用对象的引用(即只要存在对 的强引用code>Future 对象,可调用对象不能是 GCd)。 1.7 也是如此。从 1.8 开始,对它的引用取消了。但是,您无法控制您的任务将在 ExecutorService 的哪个实现上运行。

使用 WeakReference 应该在实践中作为 Future 工作,因此一旦任务完成并且理智的实现,Callable 对象就可以被 GCd当任务完成时,ExecutorService 应该失去对它的引用。严格来说,这仍然取决于 ExecutorService 的实现。此外,使用 Wea​​kReference 会增加惊人的开销。你最好直接明确地清理任何占用大量内存的对象。相反,如果您不分配大对象,那么我就不会担心。

当然,这个讨论与如果您不断向列表中添加 future 而不删除任何 future 会遇到的内存泄漏完全不同。如果您这样做,即使使用 WeakReference 也无济于事;你仍然会有内存泄漏。为此,只需遍历列表并删除已经完成因此没有用的 future 。每次都这样做真的很好,除非你有一个大得离谱的队列,因为这是非常快的。

关于java - executorService.submit(Runnable) 返回的 future 对象是否包含对可运行对象的任何引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23014606/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com