Как заставить Java-процесс завершать работу при аварийном завершении работы горячей точки - PullRequest
5 голосов
/ 19 декабря 2011

Есть ли способ обеспечить завершение всего процесса Java в случае сбоя Hotspot?

Мы размещаем собственную библиотеку в удаленном Java-процессе Windows (java.exe) в целях изоляции процесса. Однако мы обнаружили, что даже когда происходит сбой горячей точки, хотя основной поток «умирает» при сбое горячей точки, сам процесс не умирает. Мы должны убить его в диспетчере задач.

Мы думаем, что это может быть потому, что нативная библиотека сама создает свои собственные потоки, которые поддерживают процесс.

Мы хотим, чтобы весь Java-процесс умер, если произойдет сбой горячей точки.

В настоящее время наш обходной путь заключается в том, чтобы создать другой поток, который читает выходные данные порожденного процесса (в любом случае мы должны прочитать выходные данные консоли, чтобы предотвратить блокирование процесса). Мы изменили его, чтобы также явно искать сбой виртуальной машины:

private static String HOTSPOT_CRASH = "# A fatal error has been detected by the Java Runtime Environment";

public void run() {
    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        do {
            line = reader.readLine();
            if (line != null) {
                logger.info(prefix + ": " + line);
            }
            if(line.contains(HOTSPOT_CRASH)) {
                logger.error(String.format("FATAL Hotspot crash detected. Killing child process '%s'...", hostProcess));
                hostProcess.destroy();
            }
        } while (line != null);
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Но это хак: если JVM знает достаточно, чтобы выйти из системы, чтобы произошел сбой, было бы намного лучше, если бы ей сказали также завершить текущий процесс.

Есть ли способ сделать это? В идеале это должна быть опция командной строки для JVM.

1 Ответ

0 голосов
/ 19 декабря 2011

Обычно виртуальная машина завершает работу при обнаружении фатальной ошибки, но вы можете предотвратить это в своем коде.Вот несколько подсказок:

  • Проверьте родительский процесс.В Unix дочерний элемент может умереть только тогда, когда родительский процесс обрабатывает сигнал SIGCHLD (который сообщает родительскому элементу, что дочерний процесс завершен; это позволяет родительскому процессу, например, прочитать код завершения).

    Убедитесь, что вы обрабатываете выходные данные и звоните waitFor() хотя бы один раз после смерти ребенка.Это должно очистить дочерний процесс.

  • Ищите нити-демоны.Если в вашем Java-приложении есть потоки, не являющиеся демонами, они могут препятствовать выходу виртуальной машины.

    Но ошибка виртуальной машины прервет все потоки, поэтому я предполагаю, что вы никогда не очистите дочерний процесс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...