Como interrompo um processo Java normalmente no Linux e no Windows?
Quando é Runtime.getRuntime().addShutdownHook
chamado e quando não é?
E os finalizadores, eles ajudam aqui?
Posso enviar algum tipo de sinal para um processo Java de um shell?
Procuro soluções preferencialmente portáteis.
Respostas:
Os ganchos de desligamento são executados em todos os casos em que a VM não é eliminada à força. Portanto, se você emitir um kill "padrão" (
SIGTERM
de um comando kill), eles serão executados. Da mesma forma, eles serão executados após a chamadaSystem.exit(int)
.No entanto, uma morte difícil (
kill -9
oukill -SIGKILL
), então eles não serão executados. Da mesma forma (e obviamente) eles não serão executados se você puxar a energia do computador, jogá-lo em um tanque de lava fervente ou quebrar a CPU com uma marreta. Você provavelmente já sabia disso, no entanto.Os finalizadores também devem ser executados, mas é melhor não depender disso para a limpeza de desligamento, mas sim de seus ganchos de desligamento para interromper as coisas de forma limpa. E, como sempre, tome cuidado com os bloqueios (já vi muitos ganchos de desligamento travar todo o processo)!
fonte
Ok, depois de todas as possibilidades que escolhi para trabalhar com "Monitoramento e gerenciamento Java", a
Visão geral está aqui.
Isso permite que você controle um aplicativo de outro de maneira relativamente fácil. Você pode chamar o aplicativo de controle de um script para interromper o aplicativo controlado normalmente antes de eliminá-lo.
Aqui está o código simplificado:
Aplicativo controlado:
execute-o com os seguintes parâmetros da VM:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port = 9999
-Dcom.sun.management.jmxremote.authenticate = false
-Dcom.sun.management. jmxremote.ssl = false
Aplicativo de controle:
execute-o com stop ou start como o argumento da linha de comando
É isso aí. :-)
fonte
Outra maneira: seu aplicativo pode abrir um servidor de rede e esperar que uma informação chegue a ele. Por exemplo, uma string com uma palavra "mágica" :) e, em seguida, reagir para desligar: System.exit (). Você pode enviar essas informações para o socke usando um aplicativo externo como o telnet.
fonte
Aqui está uma solução um pouco complicada, mas portátil:
Implementei o Agente Java. Ele está disponível no Github: https://github.com/everit-org/javaagent-shutdown
A descrição detalhada sobre a solução está disponível aqui: https://everitorg.wordpress.com/2016/06/15/shutting-down-a-jvm-process/
fonte
Pergunta semelhante aqui
Finalizadores em Java são ruins. Eles adicionam muita sobrecarga à coleta de lixo. Evite-os sempre que possível.
O shutdownHook só será chamado quando a VM estiver sendo desligada. Acho que muito bem pode fazer o que quiser.
fonte
A sinalização no Linux pode ser feita com "kill" (man kill para os sinais disponíveis), você precisa do ID do processo para fazer isso. (ps ax | grep java) ou algo parecido, ou armazene o id do processo quando o processo for criado (isso é usado na maioria dos arquivos de inicialização do Linux, consulte /etc/init.d)
A sinalização portátil pode ser feita integrando um SocketServer em seu aplicativo java. Não é tão difícil e dá a você a liberdade de enviar qualquer comando que desejar.
Se você quis dizer finalmente cláusulas em vez de finalizadores; eles não são extintos quando System.exit () é chamado. Os finalizadores devem funcionar, mas não devem fazer nada mais significativo a não ser imprimir uma instrução de depuração. Eles são perigosos.
fonte
Obrigado por suas respostas. Os ganchos de desligamento parecem algo que funcionaria no meu caso. Mas também me deparei com a coisa chamada beans de monitoramento e gerenciamento:
http://java.sun.com/j2se/1.5.0/docs/guide/management/overview.html
Isso oferece algumas possibilidades interessantes, para monitoramento remoto e manipulação do processo java. (Foi introduzido em Java 5)
fonte