Wie stoppe ich einen Java-Prozess unter Linux und Windows ordnungsgemäß?
Wann wird Runtime.getRuntime().addShutdownHook
angerufen und wann nicht?
Was ist mit Finalisierern, helfen sie hier?
Kann ich von einer Shell aus ein Signal an einen Java-Prozess senden?
Ich suche vorzugsweise tragbare Lösungen.
Antworten:
Shutdown-Hooks werden in allen Fällen ausgeführt, in denen die VM nicht gewaltsam getötet wird. Wenn Sie also einen "Standard" -Tötung (
SIGTERM
über einen Tötungsbefehl) ausgeben, werden diese ausgeführt. Ebenso werden sie nach dem Aufruf ausgeführtSystem.exit(int)
.Jedoch ein harter Kill (
kill -9
oderkill -SIGKILL
) dann werden sie nicht ausgeführt. In ähnlicher Weise (und offensichtlich) werden sie nicht ausgeführt, wenn Sie den Computer mit Strom versorgen, ihn in einen Behälter mit kochender Lava fallen lassen oder die CPU mit einem Vorschlaghammer in Stücke schlagen. Das wussten Sie aber wahrscheinlich schon.Finalizer sollten eigentlich auch laufen, aber es ist am besten, sich beim Bereinigen des Herunterfahrens nicht darauf zu verlassen, sondern sich auf Ihre Shutdown-Hooks zu verlassen, um die Dinge sauber zu stoppen. Und wie immer, seien Sie vorsichtig mit Deadlocks (ich habe gesehen, dass viel zu viele Shutdown-Hooks den gesamten Prozess hängen)!
quelle
Ok, nach all den Möglichkeiten, die ich für die Arbeit mit "Java Monitoring and Management" gewählt habe, finden Sie
hier
eine Übersicht, mit der Sie eine Anwendung auf relativ einfache Weise von einer anderen steuern können. Sie können die steuernde Anwendung über ein Skript aufrufen, um die gesteuerte Anwendung ordnungsgemäß zu stoppen, bevor Sie sie beenden.
Hier ist der vereinfachte Code:
Kontrollierte Anwendung:
Führen Sie sie mit den folgenden VM-Parametern aus:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port = 9999
-Dcom.sun.management.jmxremote.authenticate = false
-Dcom.sun.management. jmxremote.ssl = false
Steuern der Anwendung:
Führen Sie sie mit dem Befehl stop oder start als Befehlszeilenargument aus
Das ist es. :-)
quelle
Ein anderer Weg: Ihre Anwendung kann einen Server-Socet öffnen und auf die Ankunft einer Information warten. Zum Beispiel eine Zeichenfolge mit einem "magischen" Wort :) und dann reagieren, um herunterzufahren: System.exit (). Sie können solche Informationen mit einer externen Anwendung wie Telnet an den Socke senden.
quelle
Hier ist eine etwas knifflige, aber tragbare Lösung:
Ich habe den Java Agent implementiert. Es ist auf Github verfügbar: https://github.com/everit-org/javaagent-shutdown
Eine detaillierte Beschreibung der Lösung finden Sie hier: https://everitorg.wordpress.com/2016/06/15/shutting-down-a-jvm-process/
quelle
Ähnliche Frage hier
Finalizer in Java sind schlecht. Sie erhöhen den Aufwand für die Speicherbereinigung erheblich. Vermeiden Sie sie wann immer möglich.
Der shutdownHook wird nur aufgerufen, wenn die VM heruntergefahren wird. Ich denke, es kann sehr gut tun, was Sie wollen.
quelle
Die Signalisierung unter Linux kann mit "kill" (man kill für die verfügbaren Signale) erfolgen. Dazu benötigen Sie die Prozess-ID. (ps ax | grep java) oder ähnliches oder speichern Sie die Prozess-ID, wenn der Prozess erstellt wird (dies wird in den meisten Linux-Startdateien verwendet, siehe /etc/init.d).
Die tragbare Signalisierung kann durch Integration eines SocketServers in Ihre Java-Anwendung erfolgen. Es ist nicht so schwierig und gibt Ihnen die Freiheit, jeden gewünschten Befehl zu senden.
Wenn Sie schließlich Klauseln anstelle von Finalisierern gemeint haben; Sie werden nicht ausgeführt, wenn System.exit () aufgerufen wird. Finalizer sollten funktionieren, aber eigentlich nichts Wichtigeres tun, als eine Debug-Anweisung zu drucken. Sie sind gefährlich.
quelle
Danke für deine Antworten. Shutdown hakt Nähte wie etwas, das in meinem Fall funktionieren würde. Aber ich bin auch auf das Ding namens Monitoring and Management Beans gestoßen:
http://java.sun.com/j2se/1.5.0/docs/guide/management/overview.html
Das bietet einige nette Möglichkeiten für die Fernüberwachung und -manipulation des Java-Prozesses. (Wurde in Java 5 eingeführt)
quelle