Question

Je soumets Callable objette à un ThreadPoolExecutor Et ils semblent rester en mémoire.

En regardant le vidage du tas avec l'outil MAT pour Eclipse Voir que le Callable les objets sont référencés par un FutureTask$Sync's appelant variable. Ce FutureTask$Sync est référencé par un FutureTask's synchronisation variable. Ce FutureTask est référencé par le FutureTask$Sync's Ce 0 $ variable.

J'ai lu à ce sujet (ici, ici, et sur ainsi) et il semble que le FutureTask que l'appelable est enveloppé sur le ThreadPoolExecutorSoumider () détient une référence à l'appelable pour toujours.

Ce que je suis confus, c'est comment s'assurer que le FutureTask obtient des ordures collectées afin qu'elle ne continue pas à maintenir le callable en mémoire et à maintenir tout ce que l'appelable pourrait tenir en mémoire?

Juste pour donner plus de détails sur ma situation particulière, j'essaie de mettre en œuvre le ThreadPoolExecutor D'une manière qui permet d'annuler toutes les tâches soumises si nécessaire. J'ai essayé plusieurs méthodes différentes que j'ai trouvées sur SO et ailleurs, comme la fermeture complètement de l'exécuteur (avec shutdown(), shutdownNow() etc) et à garder une liste des futurs retour par submit() et appeler l'annulation sur tous, puis effacer la liste des contrats à terme. Idéalement, je voudrais ne pas avoir à l'arrêter, et juste cancel() et effacer en cas de besoin.

Toutes ces méthodes ne semblent pas faire la différence. Si je soumets un appel à la piscine, il y a de fortes chances qu'il finisse par rester.

Qu'est-ce que je fais mal?

Merci.

Éditer:

Comme demandé, voici le constructeur du threadpoolExecutor.

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

Après d'autres tests, je peux voir que si je laisse les tâches qui ont été soumises à la finition de ThreadPoolExecutor, il n'y a pas de fuite. Si j'essaie de les annuler de toute façon comme:

shutdownNow()

Ou enregistrer une référence à l'avenir et appeler l'annulation plus tard:

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

Ou en les supprimant de la file d'attente avec des méthodes comme:

getQueue.drainTo(someList)

ou

getQueue.clear()

ou en boucle à travers des références enregistrées à l'avenir et à l'appel:

getQueue.remove(task)

L'un de ces cas provoque le respect du Futuredask comme décrit ci-dessus.

Donc, la vraie question dans tout cela est de savoir comment annuler ou supprimer correctement les éléments d'un threadpoolexecutor afin que le FutureTask soit collecté et non divulgué pour toujours?

Pas de solution correcte

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top