Come garantire la raccolta della spazzatura di un FutureTask che viene inviato a un threadPoolexecutor e quindi cancellato?

StackOverflow https://stackoverflow.com/questions/4917039

Domanda

Sto sottoponendo Callable oggetti a a ThreadPoolExecutor E sembrano rimanere in memoria.

Guardando il dump heap con lo strumento tappetino per eclipse vedi che il Callable Gli oggetti vengono referenziati da a FutureTask$Sync'S richiamabile variabile. Quella FutureTask$Sync è referenziato da a FutureTask'S sincronizzazione variabile. Quella FutureTask è referenziato dal FutureTask$Sync'S questo $ 0 variabile.

Ne ho letto in giro (qui, qui, e su così) e sembra il FutureTask che il callo sia avvolto sul ThreadPoolExecutorSubmit () detiene un riferimento al callo per sempre.

Ciò di cui sono confuso è come assicurarsi che il FutureTask Viene raccolto la spazzatura in modo che non continui a mantenere la callone in memoria e tieni in mancherlibile che la callabile potrebbe tenere in memoria?

Solo per fornire maggiori dettagli sulla mia situazione particolare, sto cercando di implementare il ThreadPoolExecutor In un modo che consente di annullare tutte le attività presentate se necessario. Ho provato diversi metodi che ho trovato su così e altrove, come chiudere completamente l'esecutore (con shutdown(), shutdownNow() ecc) e anche mantenere un elenco del ritorno di futures da submit() e chiamare Annulla su tutti loro e quindi cancellare l'elenco dei futuri. Idealmente vorrei non doverlo chiuderlo, e solo cancel() e cancella quando necessario.

Tutti questi metodi non sembrano fare la differenza. Se invio un calling al pool, ci sono buone probabilità che finirà per restare in giro.

Che cosa sto facendo di sbagliato?

Grazie.

Modificare:

Come richiesto, ecco il costruttore per ThreadPoolexecutor.

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

Dopo ulteriori test, posso vedere che se ho lasciato che le attività che sono state inviate alla finitura di ThreadPoolexecutor, non vi è alcuna perdita. Se provo a annullarli comunque come:

shutdownNow()

O salvare un riferimento al futuro e chiamare Annulla in seguito:

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

O rimuovendoli dalla coda con metodi come:

getQueue.drainTo(someList)

o

getQueue.clear()

o loop attraverso riferimenti salvati ai futuri e alla chiamata:

getQueue.remove(task)

Qualsiasi di questi casi fa sì che il futuretask si attacchi come descritto sopra.

Quindi la vera domanda in tutto questo è come annullare correttamente o rimuovere gli articoli da un threadpoolexecutor in modo che il futuretask sia raccolta e non trapelata per sempre?

Nessuna soluzione corretta

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top