我正在向Callablea 提交对象ThreadPoolExecutor,它们似乎在记忆中徘徊.
寻找与Eclipse的MAT工具堆转储看到Callable的物体正在被引用FutureTask$Sync的可调用的变量.这FutureTask$Sync是由一个被引用FutureTask的同步变量.这FutureTask是由引用FutureTask$Sync的这个$ 0变量.
我已经读过这个(这里,这里,以及SO),似乎FutureTask可调用包含在ThreadPoolExecutor's submit()中,它永远保存了对callable的引用.
我感到困惑的是如何确保FutureTask收集垃圾,以便它不会继续保持内存中的可调用内容,并保存可调用内容可能保留在内存中的任何内容?
只是为了提供有关我的特定情况的更多详细信息,我试图以ThreadPoolExecutor允许在需要时取消所有提交的任务的方式实现它.我尝试了好几种不同的方法,我发现在SO和其他地方,如完全查封了执行者(与shutdown(),shutdownNow()等),并保持期货的列表中返回submit(),并呼吁取消所有的人,然后清除期货的列表.理想情况下,我不想将其关闭,只需cancel()在需要时清除.
所有这些方法似乎没有什么区别.如果我向游泳池提交一个可调用的游戏,它很可能会最终粘在游泳池中.
我究竟做错了什么?
谢谢.
编辑:
根据要求,这是ThreadPoolExecutor的构造函数.
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
Run Code Online (Sandbox Code Playgroud)
经过进一步测试后,我可以看到,如果我让已经提交给ThreadPoolExecutor的任务完成,那么就没有泄漏.如果我试图取消它们,例如:
shutdownNow()
Run Code Online (Sandbox Code Playgroud)
或保存对未来的引用并稍后调用取消:
Future referenceToCancelLater = submit(task); …Run Code Online (Sandbox Code Playgroud)