Wo fange ich an, meinen Java-Prozess zu untersuchen, der nicht enden wird?

9

Ich habe eine Java-Anwendung, die nicht endet. Die Hauptmethode wird beendet, die Threads bleiben jedoch aktiv und die Anwendung wird nicht beendet. Die Sache ist, es scheint keine Monitor-Sperren / Wartezeiten zu geben, also kann ich nicht sehen, warum es nicht aufhört. Laut Eclipse habe ich zwei Nicht-Daemon-Threads. Einer ist mit [DestroyJavaVM] gekennzeichnet (sieht hoffnungsvoll aus!) Und der andere scheint in Unsafe.park(boolean, long) blockiert zu sein. Wie / wo soll ich das untersuchen?

Der abgekürzte Stacktrace des zweiten Threads ist:

%Vor%     
JenFallow 13.07.2010, 10:57
quelle

5 Antworten

1

Sie müssen eines von zwei Dingen tun, um Ihren ExecutorService thread zu beenden:

  1. Geben Sie eine ThreadFactory ein, die Daemon-Threads erstellt (die ThreadFactoryBuilder -Klasse von Guava macht dies möglich) einfacher.)
  2. Rufen Sie shutdown() auf Ihrem ExecutorService als Teil des Anwendungs-Shutdown auf (z. B. am Ende Ihrer main -Methode.)
finnw 13.07.2010 11:17
quelle
0

Thread-Dumps und Debugger wären meine Vermutung.

    
duffymo 13.07.2010 10:59
quelle
0

Ich bin mir nicht sicher, wie groß die Anwendung ist, aber ich würde alle erstellten Threads überprüfen und sicherstellen, dass ihre Ausführungsmethoden sauber beendet werden, wenn die Anwendung ausgeführt wird. Irgendwo, innerhalb eines Threads, haben Sie möglicherweise Code in den folgenden Zeilen:

%Vor%     
gMale 13.07.2010 11:05
quelle
0

Unsafe.park wird trotz des erschreckend klingenden Namens normalerweise von allen Arten von blockierenden Aufrufen verwendet (besonders von denen im neuen (ish) java.util.concurrent -Paket).

Wenn Sie sich ein paar Frames weiter unten im Stack ansehen, sehen Sie etwas wie java.util.concurrent.LinkedBlockingQueue.take (dh eine JDK-Bibliotheksklasse) gefolgt von etwas wie com.example.myapp.MyClass.getNextJob (dh Ihre Klasse, die die Bibliotheksklasse verwendet) / p>

Wenn ich eine Vermutung riskieren müsste, würde ich sagen, dass Sie irgendeine Art von Anruf machen, der für immer blockiert - und wenn dann nichts mehr zurückkommt, sitzt dieser Thread einfach dort und wartet auf den "nächsten" Gegenstand. Sie könnten dies lösen, indem Sie eine Art "Fertig" -Flag setzen und dann entweder den wartenden Thread unterbrechen oder dem blockierenden Anruf ein Timeout geben, um ihn dazu zu bringen, das Flag zu prüfen. Abhängig von deinem Code könnte eine dieser beiden oder eine Alternative machbar sein, aber hoffentlich ist das genug, um dich anzufangen.

Bearbeiten: Nachdem der Stacktrace angezeigt wurde, Finnw ist richtig , dass Sie Ihren Executor-Dienst herunterfahren müssen.

    
Andrzej Doyle 13.07.2010 11:07
quelle
0

Ihre Aufgabe ist blockiert und wartet auf Daten aus der Warteschlange. Take hat kein Timeout.

Pflegen Sie einen Verweis auf Ihren Aufgaben-Thread, wenn er erstellt wird. Rufen Sie beim Herunterfahren die Interrupt-Methode für den Thread auf. Möglicherweise müssen Sie auch die Arbeitsverarbeitungsschleife ändern, die zum Beenden aufgerufen wird, wenn InterruptedException abgefangen wird.

    
Jim Rush 13.07.2010 11:43
quelle

Tags und Links