2014-01-11 2 views
0
  1. Если я получил его правильно, каждый процесс java связан с отдельным экземпляром JVM, и каждый экземпляр JVM снабжен оперативной памятью ОС, которая также запоминается ОС при завершении JVM , 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 верна, почему мы должны использовать выключатели остановки. После googling все в основном предлагает освободить все ресурсы и грациозное закрытие. Even if it does not gracefully shutdown all the memory and resources would be freed?
  3. Я написал простой крюк остановки. В моем основном потоке я запускаю бесконечный цикл, а затем завершаю процесс с помощью кнопки завершения в Eclipse. Но нить крюка отключения не работает. Завершает ли процесс завершения в eclipse Runtime.getRuntime().halt(status), потому что AFAIK неожиданно прекратил JVM и не выполнил выключение?
  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?

ответ

3

1) Вы правильно.

2) Память процесса Java будет восстановлена, но вы можете захотеть выполнить другую очистку, например, удалить некоторые временные файлы.

3) Пойдемте к Javadoc из Runtime#addShutdownHook(Thread)

Виртуальная машина Java выключается в ответ на два вида событий:

  • Программа выходит нормально, когда последний выход не-демона или при вызове метода exit (эквивалентно, System.exit) или

  • Виртуальная машина завершается в ответ на прерывание пользователя, , например, набирает^C или общесистемное событие, такое как выключение пользователя или выключение системы.

Вы должны посмотреть в исходный код в Eclipse, но это, казалось бы, как Eclipse, завершает процесс, а не отправки System.exit(..) или отправки прерывания пользователя. Вероятно, это происходит через JVM, поэтому он не выполняет крючки отключения.

4) остановленных крючки добавляемые с Runtime#addShutdownHook(Thread) добавляют к staticIdentityHashMap в 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() не выполняется.

Смежные вопросы