Java Runtime#halt() не останавливает JVM
Это клиент-серверное приложение, использующее RMI. Как только запрос RMI получен сервером для destroy() - мне нужно прервать виртуальную машину. я использую Runtime.getRuntime().halt(0)
для этого. Но после вызова halt() виртуальная машина все еще существует, и единственный способ убить ее - использовать Force Kill
на OSX.
Трассировка стека для вызывающего потока выглядит следующим образом:
"RMI TCP Connection(3)-192.168.1.4" daemon prio=5 tid=7f99a7103000 nid=0x11d467000 runnable [11d464000]
java.lang.Thread.State: RUNNABLE
at java.lang.Shutdown.halt0(Native Method)
at java.lang.Shutdown.halt(Shutdown.java:95)
- locked <7f44c90d0> (a java.lang.Shutdown$Lock)
at java.lang.Runtime.halt(Runtime.java:256)
at net.sourceforge.marathon.runtime.JavaRuntime.destroy(JavaRuntime.java:178)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at net.sourceforge.rmilite.impl.RemoteInvocationHandlerImpl.invoke(RemoteInvocationHandlerImpl.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:303)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
В чем может быть проблема?
2 ответа
Я пробовал несколько вещей, чтобы сделать эту работу.
- добавленной
Runtime#runFinalization
перед вызовом остановить (). - Вызванный
halt()
вSwingUtilities.invokeAndWait
- Вызванный
halt()
вSwingUtilities.invokeLater
Ничто из этого не сработало. В заключение,
- Вызванный
halt()
в задаче таймера с использованиемTimer#schedule
Это работало и последовательно работает до сих пор. Спасибо всем за ответы.
Когда вы получаете команду destroy(), вы должны:
- Удалить все удаленные объекты.
- Неэкспортируйте любые реестры.
- Удалите все статические ссылки на удаленные объекты и реестры.
Затем JVM автоматически выйдет из системы, если только у вас не запущены потоки, не являющиеся демонами.