So on termination even if there were some memory leaks all the memory will be reclaimed by the OS(Please correct if I have mistaken)
。Even if it does not gracefully shutdown all the memory and resources would be freed?
Eclipse
中的终止按钮终止进程。但是关闭钩子线程没有运行。
eclipse中的终止进程是否调用Runtime.getRuntime().halt(status)
,因为AFAIK突然终止了JVM而没有执行shutdown hook?最后,如果我的主要代码如下所示 -
public static void main(String args[]){
Runtime.getRuntime().addShutdownHook(new Thread(new ShutDownHook()));
System.out.println("Shutdown hook registered");
System.out.println("Before calling exit");
System.exit(0);
System.out.println("After exit");
}
为什么不打印After exit
?当执行shutdown hook时,主线程必须继续执行并打印After exit
?
答案 0 :(得分:3)
1)你是对的。
2)将回收Java进程的内存,但您可能希望进行其他清理,例如删除一些临时文件。
3)让我们转到Runtime#addShutdownHook(Thread)
Java虚拟机关闭以响应两种 事件:
当最后一个非守护程序线程退出或时,程序正常退出 何时调用exit(等效,System.exit)方法,或
虚拟机终止以响应用户中断, 例如键入^ C或系统范围的事件,例如用户注销或 系统关闭。
您必须查看Eclipse的源代码,但似乎Eclipse会终止该进程而不是发送System.exit(..)
或发送用户中断。这可能会超过JVM,因此不会执行关闭挂钩。
4)您使用Runtime#addShutdownHook(Thread)
添加的关闭挂钩已添加到static
中的IdentityHashMap
ApplicationShutdownHooks
。该类在Shutdown
初始化程序块中使用static
类注册自己的关闭挂钩
static {
try {
Shutdown.add(1 /* shutdown hook invocation order */,
false /* not registered if shutdown in progress */,
new Runnable() {
public void run() {
runHooks();
}
}
);
hooks = new IdentityHashMap<>();
} catch (IllegalStateException e) {
// application shutdown hooks cannot be added if
// shutdown is in progress.
hooks = null;
}
}
runHooks()
方法
static void runHooks() {
Collection<Thread> threads;
synchronized(ApplicationShutdownHooks.class) {
threads = hooks.keySet();
hooks = null;
}
for (Thread hook : threads) {
hook.start();
}
for (Thread hook : threads) {
try {
hook.join();
} catch (InterruptedException x) { }
}
}
所以当前线程加入了所有其他线程。
何时
System.exit(0);
被调用,调用行Shutdown.sequence()
的某个地方调用Shutdown.hooks()
实现为
private static void runHooks() {
for (int i=0; i < MAX_SYSTEM_HOOKS; i++) {
try {
Runnable hook;
synchronized (lock) {
// acquire the lock to make sure the hook registered during
// shutdown is visible here.
currentRunningHook = i;
hook = hooks[i];
}
if (hook != null) hook.run();
} catch(Throwable t) {
if (t instanceof ThreadDeath) {
ThreadDeath td = (ThreadDeath)t;
throw td;
}
}
}
}
Runnable
中的hooks
个对象之一就是我上面描述的内容。它不会产生新的Thread
,而是与run()
同时产生。
完成Shutdown.sequence()
后,系统确实退出,因此最终的System.out.println()
不会执行。