Nehmen wir an, wir haben den folgenden Code:
%Vor%Meine Fragen sind:
runningTasks
eine Referenz auf das Objekt task
? Bis zum Zeitpunkt, an dem der Executor oder das Objekt Future
einen Verweis darauf enthält, ist ein Implementierungsdetail . Wenn Ihre Aufgaben daher viel Speicher belegen, sodass Sie sich Gedanken über die Speichernutzung machen müssen, sollten Sie Ihre Aufgabe vor dem Abschluss der Aufgabe explizit bereinigen.
Wenn Sie sich OpenJDK 1.6 Quelltext von ThreadPoolExecutor
, Sie können sehen, dass tatsächlich das zugrunde liegende Future
Objekt tatsächlich einen Verweis auf das zugrunde liegende aufrufbare Objekt auf unbestimmte Zeit behält (d Solange es eine starke Referenz auf das Future
-Objekt gibt, kann das Callable nicht GCd sein. Dies gilt auch für 1,7. Ab 1.8 wird der Verweis auf annulliert. Sie können jedoch nicht steuern, auf welche Implementierung von ExecutorService
Ihre Aufgabe ausgeführt wird.
Die Verwendung von WeakReference
sollte in der Praxis funktionieren, da das Future
und somit das Callable
-Objekt GCd sein kann, sobald die Aufgabe erledigt ist und vernünftige Implementierungen von ExecutorService
den Bezug verlieren sollten, wenn die Aufgabe erledigt ist. Genau genommen hängt dies jedoch immer noch von der Implementierung des ExecutorService ab. Darüber hinaus kann die Verwendung von WeakReference einen überraschend großen Overhead hinzufügen. Es ist viel besser, das Objekt, das viel Speicher beansprucht, einfach explizit zu bereinigen. Umgekehrt, wenn Sie keine großen Objekte zuweisen, würde ich mir keine Sorgen machen.
Natürlich ist diese Diskussion völlig anders als das Speicherleck, das Sie haben werden, wenn Sie weiterhin Futures zu Ihrer Liste hinzufügen, ohne sie jemals zu entfernen. Wenn Sie dies tun, würde sogar die Verwendung von WeakReference
nicht helfen. Sie haben immer noch ein Speicherleck. Durchlaufen Sie dazu einfach die Liste und entfernen Sie bereits getätigte Futures, die Ihnen nichts nützen. Es ist wirklich in Ordnung, dies jedes Mal zu tun, es sei denn, Sie haben eine lächerlich große Warteschlange Größe, da dies sehr schnell ist.
Future
verwenden. Wenn Sie ScheduledFuture
verwenden, können Speicherleckprobleme auftreten, da ScheduledFuture.cancel()
oder Future.cancel()
im Allgemeinen seine Executor
nicht benachrichtigen, dass sie abgebrochen wurde, und sie in der Warteschlange verbleibt, bis ihre Ausführungszeit erreicht ist ist eingetroffen. Es ist keine große Sache für einfache Futures, aber kann ein großes Problem für ScheduledFutures
sein. Es kann dort für Sekunden, Minuten, Stunden, Tage, Wochen, Jahre oder fast unbegrenzt bleiben, abhängig von den Verzögerungen, mit denen es geplant wurde.
Weitere Einzelheiten zum Beispiel der Speicherlecksituation und ihrer Lösung finden Sie in den anderen Antwort .
Tags und Links java future executorservice runnable