¿Cómo garantizar la recolección de basura de una FuturetAk que se envía a un ThreadpoolExecutor y luego se cancela?

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

Pregunta

Estoy enviando Callable objetos a un ThreadPoolExecutor Y parecen estar quedando en la memoria.

Mirando el volcado de montón con la herramienta Mat para Eclipse, vea que el Callable Los objetos están siendo referenciados por un FutureTask$Sync's llamable variable. Que FutureTask$Sync se hace referencia por un FutureTask's sincronización variable. Que FutureTask se hace referencia por el FutureTask$Sync's este $ 0 variable.

He leído sobre esto (aquí, aquí, y en eso) y parece el FutureTask que el llamado está envuelto en el ThreadPoolExecutor'S SENT () tiene una referencia al llamable para siempre.

Lo que estoy confundido es cómo asegurar que el FutureTask ¿Obtiene la basura recolectada para que no continúe manteniendo el llamable en la memoria y mantenga cualquier cosa que el llamable pueda estar conteniendo en la memoria?

Solo para dar más detalles sobre mi situación particular, estoy tratando de implementar el ThreadPoolExecutor de manera que permita que todas las tareas enviadas se cancelen si es necesario. He probado varios métodos diferentes que encontré en So y en otros lugares, como cerrar completamente el ejecutor (con shutdown(), shutdownNow() etc) y también mantener una lista de los futuros retorno de submit() y llamar a Cancelar en todos ellos y luego a borrar la lista de futuros. Idealmente, me gustaría no tener que apagarlo, y solo cancel() y borrar cuando sea necesario.

Todos estos métodos no parecen marcar la diferencia. Si envío un llamado a la piscina, hay una buena posibilidad de que termine quedando.

¿Qué estoy haciendo mal?

Gracias.

Editar:

Según lo solicitado, aquí está el constructor para ThreadPoolExecutor.

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

Después de más pruebas, puedo ver que si dejo que las tareas que se han enviado al TreadPoolExecutor finalizan, entonces no hay fuga. Si intento cancelarlos de todos modos, como:

shutdownNow()

O guardar una referencia al futuro y llamar a Cancelar en él más tarde:

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

O quitándolos de la cola con métodos como:

getQueue.drainTo(someList)

o

getQueue.clear()

o recorrer a través de referencias guardadas a los futuros y llamar:

getQueue.remove(task)

Cualquiera de esos casos hace que la FuturetASK se quede como se describió anteriormente.

Entonces, la verdadera pregunta en todo esto es cómo cancelar o eliminar adecuadamente los elementos de un ThreadpoolExecutor para que la FuturetAk sea basura recolectada y no se filtre para siempre.

No hay solución correcta

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top