Как обеспечить сборку мусора FutureTask, который передается в ThreadPoolExecutor, а затем отменяется?

Я отправляю вызываемые объекты в ThreadPoolExecutor , и они, похоже, прилипают

Глядя на дамп кучи с помощью инструмента MAT для Eclipse, можно увидеть, что на Callable объекты ссылаются вызываемые FutureTask $ Sync вызываемые переменная. На FutureTask $ Sync ссылается переменная FutureTask sync . На FutureTask ссылается FutureTask $ Sync эта переменная $ 0 .

Я читал об этом ( здесь , здесь и SO), и похоже, что FutureTask , вызываемый объект заключен в ThreadPoolExecutor submit () содержит ссылку на вызываемый навсегда.

Что меня смущает, так это то, как обеспечить, чтобы FutureTask собирал мусор, чтобы он не продолжал удерживать вызываемый объект в памяти и удерживать все, что вызываемый объект может удерживать в памяти ?

Просто чтобы подробнее рассказать о моей конкретной ситуации, Я пытаюсь реализовать ThreadPoolExecutor таким образом, чтобы при необходимости можно было отменить все отправленные задачи. Я пробовал несколько различных методов, которые я нашел на SO и в других местах, например, полное выключение исполнителя (с помощью shutdown () , shutdownNow () и т. Д.), А также ведение списка фьючерсы возвращаются с помощью submit () и вызывают отмену для всех них, а затем очищают список фьючерсов. В идеале я бы хотел не выключать его, а просто cancel () и очищать при необходимости.

Все эти методы, похоже, не имеют значения. Если я отправлю вызываемый объект в пул, велика вероятность, что он в конечном итоге останется.

Что я делаю не так?

Спасибо.

Изменить:

По запросу, вот конструктор ThreadPoolExecutor.

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) {
    super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}

После дальнейшего тестирования я вижу, что если я позволю задачам, которые были отправлены в ThreadPoolExecutor, завершиться, то утечки не будет. Если я попытаюсь отменить их каким-либо образом, например:

shutdownNow()

Или сохраняю ссылку на будущее и вызываю отмену для нее позже:

Future referenceToCancelLater = submit(task);
...
referenceToCancelLater.cancel(false);

Или удаляя их из очереди такими методами, как:

getQueue.drainTo(someList)

или

getQueue.clear()

или Цикл по сохраненным ссылкам на фьючерсы и вызов:

getQueue.remove(task)

Любой из этих случаев приводит к тому, что FutureTask остается, как описано выше.

Итак, реальный вопрос во всем этом - как правильно отменить или удалить элементы из ThreadPoolExecutor так что FutureTask собирает мусор и не утекает навсегда?

9
задан cottonBallPaws 7 February 2011 в 05:51
поделиться