Что может заставить Java продолжать бегать за System.exit ()?

У меня есть программа Java, которая запускается через ProcessBuilder из другой программы Java. System.exit(0) назван из дочерней программы, но для некоторых наших пользователей (в Windows) java.exe процесс, связанный с ребенком, не завершается. Дочерняя программа не имеет никаких рычагов завершения работы, и при этом она не имеет a SecurityManager который мог бы остановиться System.exit() от завершения VM. Я не могу воспроизвести проблему сам на Linux или Windows Vista. До сих пор единственные сообщения о проблеме приходят от двух пользователей Windows XP и одного пользователя Vista, с помощью двух различных JREs (1.6.0_15 и 1.6.0_18), но они могут воспроизвести проблему каждый раз.

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

Редактирование 1: Я заставил пользователя устанавливать JDK, таким образом, мы могли получить дамп потока от оскорбления VM. То, что пользователь сказал мне, - то, что процесс VM исчезает из VisualVM, как только он нажимает на объект 'Выхода' в моем меню---, но, согласно Windows Task Manager, процесс не завершился, и неважно сколько времени пользователь ожидает (минуты, часы), это никогда не завершается.

Редактирование 2: Я подтвердил теперь, когда Process.waitFor() в родительской программе никогда не возвращается для по крайней мере одного из пользователей, имеющих проблему. Так, для суммирования: дочерний VM, кажется, мертв (VisualVM даже не видит его), но родитель все еще рассматривает процесс как живой и Windows - также.

20
задан uckelman 11 April 2010 в 18:30
поделиться

4 ответа

Вот пара сценариев ...

Согласно определению потока в http://java.sun.com/ j2se / 1.4.2 / docs / api / java / lang / Thread.html

...

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

1) Был вызван метод выхода класса Runtime, и диспетчер безопасности разрешил выполнение операции выхода. 2) Все потоки, которые не являются потоками демона, умерли либо в результате возврата из вызова к методу run, либо в результате выдачи исключения, которое распространяется за пределы метода run.

Другая возможность - если был вызван метод runFinalizersOnExit. согласно документации в http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html Устарело. Этот метод по своей сути небезопасен. Это может привести к тому, что финализаторы будут вызваны для живых объектов, в то время как другие потоки одновременно манипулируют этими объектами, что приведет к неустойчивому поведению или тупиковой ситуации. Включить или отключить финализацию при выходе; это указывает, что финализаторы всех объектов, у которых есть финализаторы, которые еще не были автоматически вызваны, должны быть запущены до выхода из среды выполнения Java. По умолчанию завершение при выходе отключено. Если есть диспетчер безопасности, его метод checkExit сначала вызывается с 0 в качестве аргумента, чтобы убедиться, что выход разрешен. Это может привести к исключению SecurityException.

4
ответ дан 30 November 2019 в 01:02
поделиться

Использует ли родительский процесс поток ошибок и выходной поток от дочернего процесса? Если в какой-либо ОС дочерний процесс выводит некоторые ошибки / предупреждения на stdout / stderr, а родительский процесс не использует потоки, childprocess заблокируется и не достигнет System.exit ();

1
ответ дан 30 November 2019 в 01:02
поделиться

Может быть, плохо написанный финализатор? Когда я прочитал тему письма, моей первой мыслью было отключение. Предположение: может ли поток, который перехватывает InterruptedException и продолжает работать, в любом случае, задерживать процесс выхода?

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

Вы уверены, что ребенок все еще работает и что это не просто невыполненный зомби-процесс?

1
ответ дан 30 November 2019 в 01:02
поделиться

Я думаю, что все очевидные причины были временно покрыты; например финализаторы, хуки выключения, некорректное сливание стандартного вывода / стандартной ошибки в родительском процессе. Теперь вам нужно больше доказательств, чтобы понять, что происходит.

Предложения:

  1. Настройте машину с Windows XP или Vista (или виртуальную), установите соответствующую JRE и свое приложение и попытайтесь воспроизвести проблему. Как только вы сможете воспроизвести проблему, подключите отладчик или отправьте соответствующий сигнал, чтобы получить дамп потока до стандартной ошибки.

  2. Если вы не можете воспроизвести описанную выше проблему, попросите одного из ваших пользователей сделать дамп потока и переслать вам файл журнала.

0
ответ дан 30 November 2019 в 01:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: