如何优雅地停止java进程?
如何在Linux和Windows中优雅地停止Java进程?如何优雅地停止java进程?
Runtime.getRuntime().addShutdownHook
何时被调用,什么时候不调用?
终结者怎么样,他们在这里帮助吗?
我可以从shell发送某种信号给Java进程吗?
我在寻找最好的便携式解决方案。
回答:
关闭挂钩在虚拟机未被强行杀死的所有情况下执行。因此,如果您要发出“标准”杀死(kill命令中的SIGTERM
),那么它们将执行。同样,他们将在致电System.exit(int)
后执行。
但是一个硬杀(kill -9
或kill -SIGKILL
),那么他们将不会执行。同样的(显然),如果你从计算机中取出电源,将它放入沸腾的熔岩桶中,或者用大锤击碎CPU,它们将不会执行。不过,你可能已经知道了。
终结器真的应该运行,但最好不要依赖于关闭清理,而是依靠你的关闭钩子干净地停止事情。和往常一样,要小心死锁(我已经看到太多的关机挂钩挂在整个过程中)!
回答:
相似问题Here
Java中的终结器是不好的。它们为垃圾收集增加了很多开销。尽可能避免使用它们。
shutdownHook只会在VM关闭时被调用。我认为它可以做你想做的事。
回答:
在关机的情况下,您是否阅读过javadoc?在Linux中
https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#addShutdownHook-java.lang.Thread-
回答:
信号可以“杀”(人杀死可用的信号)来完成,你需要的进程ID做到这一点。 (ps ax | grep java)或类似的东西,或者当进程被创建时存储进程ID(这在大多数linux启动文件中使用,参见/etc/init.d)
便携信令可以通过在您的Java应用程序中集成SocketServer。这并不困难,并让您自由发送任何您想要的命令。
如果您的意思是最终条款而不是终结者;当System.exit()被调用时它们不会被扩展。 终结器应该可以工作,但不应该做任何更重要的事情,但应该打印调试声明。他们很危险。
回答:
谢谢你的答案。关闭钩子接缝就像在我的情况下工作。 但我也碰到了一个叫做Monitoring and Management beans的东西:
http://java.sun.com/j2se/1.5.0/docs/guide/management/overview.html
这给了一些很好的可能性,用于远程监控和操作java进程。(在Java 5中经人介绍)
回答:
好吧,毕竟我已经选择与“Java监视和管理”
Overview is here
这允许你从另外一个相对简单的方式控制一个应用程序的工作准备。您可以从脚本中调用控制应用程序,以便在杀死它之前正常停止受控应用程序。
这里是简化的代码:
受控应用:
与如下因素VM参数运行:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote .port = 9999
-Dcom.sun.management.jmxremote.authenticate =假
-Dcom.sun.management.jmxremote.ssl =假
//ThreadMonitorMBean.java public interface ThreadMonitorMBean
{
String getName();
void start();
void stop();
boolean isRunning();
}
// ThreadMonitor.java
public class ThreadMonitor implements ThreadMonitorMBean
{
private Thread m_thrd = null;
public ThreadMonitor(Thread thrd)
{
m_thrd = thrd;
}
@Override
public String getName()
{
return "JMX Controlled App";
}
@Override
public void start()
{
// TODO: start application here
System.out.println("remote start called");
}
@Override
public void stop()
{
// TODO: stop application here
System.out.println("remote stop called");
m_thrd.interrupt();
}
public boolean isRunning()
{
return Thread.currentThread().isAlive();
}
public static void main(String[] args)
{
try
{
System.out.println("JMX started");
ThreadMonitorMBean monitor = new ThreadMonitor(Thread.currentThread());
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("com.example:type=ThreadMonitor");
server.registerMBean(monitor, name);
while(!Thread.interrupted())
{
// loop until interrupted
System.out.println(".");
try
{
Thread.sleep(1000);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
// TODO: some final clean up could be here also
System.out.println("JMX stopped");
}
}
}
控制应用:
与停止或开始作为命令行参数
public class ThreadMonitorConsole {
public static void main(String[] args)
{
try
{
// connecting to JMX
System.out.println("Connect to JMX service.");
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
// Construct proxy for the the MBean object
ObjectName mbeanName = new ObjectName("com.example:type=ThreadMonitor");
ThreadMonitorMBean mbeanProxy = JMX.newMBeanProxy(mbsc, mbeanName, ThreadMonitorMBean.class, true);
System.out.println("Connected to: "+mbeanProxy.getName()+", the app is "+(mbeanProxy.isRunning() ? "" : "not ")+"running");
// parse command line arguments
if(args[0].equalsIgnoreCase("start"))
{
System.out.println("Invoke \"start\" method");
mbeanProxy.start();
}
else if(args[0].equalsIgnoreCase("stop"))
{
System.out.println("Invoke \"stop\" method");
mbeanProxy.stop();
}
// clean up and exit
jmxc.close();
System.out.println("Done.");
}
catch(Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
就是这样运行它。 :-)
回答:
另一种方式:您的应用程序可以打开一个服务器socet并等待一个信息到达它。例如一个带有“魔术”字符的字符串:)然后做出关闭:System.exit()的反应。您可以使用外部应用程序(如telnet)将这些信息发送到socke。
回答:
这是一个有点棘手,但便携的解决方案:
- 在您的应用程序当你想正常关闭您的JVM,安装Java Agent调用System.exit实施关闭挂钩
- ( )使用Attach API。
我实现了Java代理。它可以在Github上:https://github.com/everit-org/javaagent-shutdown
有关解决方案的详细说明,请访问:https://everitorg.wordpress.com/2016/06/15/shutting-down-a-jvm-process/
以上是 如何优雅地停止java进程? 的全部内容, 来源链接: utcz.com/qa/258230.html