0
  1. 私が正しく取得した場合、各JavaプロセスはJVMの個別のインスタンスに関連付けられ、JVMの各インスタンスにはOSによってヒープメモリが提供され、JVMの終了時にOSによって再収集されます。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).
  2. ポイント番号 1 が当てはまる場合、シャットダウン フックを使用する必要があるのはなぜですか。グーグルで調べた後、主にすべてのリソースを解放し、正常にシャットダウンすることをお勧めします。Even if it does not gracefully shutdown all the memory and resources would be freed?
  3. 簡単なシャットダウンフックを書きました。私のメインスレッドでは、無限ループを実行してから、終了ボタンを使用してプロセスを終了していますEclipse。しかし、シャットダウン フック スレッドは実行されていません。Runtime.getRuntime().halt(status)JVMを突然終了し、シャットダウンフックを実行しないAFAIKが原因で、Eclipse呼び出しでプロセスを終了しますか?
  4. 最後に、以下のようなメインコードがある場合-

    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印刷されないのですか?シャットダウンフックが実行中の場合、メインスレッドはさらに実行を続けて出力する必要がありますAfter exitか?

4

1 に答える 1

3

1)あなたは正しいです。

2) Java プロセスのメモリは再利用されますが、いくつかの一時ファイルを削除するなど、他のクリーンアップを実行することもできます。

3)の javadoc に行きましょうRuntime#addShutdownHook(Thread)

Java 仮想マシンは、次の 2 種類のイベントに応答してシャットダウンします。

  • 最後の非デーモン スレッドが終了するか、exit (同等の System.exit) メソッドが呼び出されると、プログラムは正常に終了します。

  • 仮想マシンは、^C の入力などのユーザー割り込み、またはユーザー ログオフやシステム シャットダウンなどのシステム全体のイベントに応答して終了します。

System.exit(..)Eclipse のソース コードを調べる必要がありますが、Eclipse は、またはユーザー割り込みを送信するのではなく、プロセスを終了するように見えます。これはおそらく JVM を通過するため、シャットダウン フックは実行されません。

4)で追加したシャットダウン フックは、 のRuntime#addShutdownHook(Thread)a に追加され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のオブジェクトの 1 つは、hooks上で説明したものです。新しいThreadを生成するのではなく、 と同時に実行しrun()ます。

完了Shutdown.sequence()すると、システムは実際に終了するため、ファイナルSystem.out.println()は実行されません。

于 2014-01-11T19:50:32.700 に答える