2013-10-07 3 views
1

У меня есть утилита, где Jmeter отправляет запрос, и утилита отправляет ответ на Jmeter. Когда загрузка увеличивается, утилита отключается с помощью «EXCEPTION_ACCESS_VIOLATION».Почему мой процесс висит на input.readLine()?

Поскольку это ошибка, я не могу обработать ее в блоке catch. Я сделал вторую утилиту для перезапуска первой утилиты при возникновении ошибки. Ниже приведен код второго, перезапуска, утилиты. В этом коде второй утилиты, на секунд, а, моя программа иногда зависает. Как это обнаружить и перезапустить процесс?

public static void main(String[] args) 
{ 
    String line = null; 
    String currPID = null; 
    try 
    { 
     while(true) 
     { 
      Process process = Runtime.getRuntime().exec("java -XX:+HeapDumpOnOutOfMemoryError -Xms250M -Xmx500M -XX:ErrorFile=NUL ws "); 
      BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); 
      while ((line = input.readLine()) != null) //Program stucks at this Line 
      { 
       if(line.trim().length() != 0) 
       { 
        if(line.startsWith("PID")) 
        { 
         currPID = line.substring(line.indexOf("@")+1); 
        } 
       } 
      } 
      System.out.println("Ended"); 
     } 
    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 
} 

Я проанализировал процесс через jvisualvm, где я нашел два процесса Java находится в рабочем режиме, когда я начать второй (перезапуск) полезность. Я вижу, что первая утилита перезапускается регулярно, потому что ее PID часто меняется в jvisualvm и то же самое происходит в диспетчере задач. Все идет очень хорошо.

После некоторого времени я обнаружил, что только один процесс находится в Jvisualvm, то есть второй (повторной) утилите. Это означает, что первая утилита JVM разбилась, просто гадая, не уверен. Здесь происходит что-то необычное. Потому что, если JVM разбился, поэтому он должен быть перезапущен. Итак, я открыл диспетчер задач и нашел первую полезность PID существует, но он не меняется, как происходит при запуске. Если я немедленно уничтожу процесс (первая утилита) из диспетчера задач. Утилита Seconds снова перезапускает первую утилиту, то же самое происходит снова, через некоторое время первая утилита исчезла из jvisualvm, существует в taskmanager и удаляет процесс из taskmanager. Что нужно делать?

+0

Вы можете обработать ошибку в блоке 'catch', добавив блок catch для catch класса' Error' в дополнение к 'Exception' или просто' Throwable', если это тестовый код. См. Здесь для получения дополнительной информации: http://stackoverflow.com/questions/15190164/catching-all-java-lang-error-for-logging-purposes-and-allowing-them-to-work-thei – JoshDM

+0

Но где положить catch блок для ошибки. Это может нарушить нормальный поток программы. – Deepak

+0

На данный момент целью является попытка захвата трассировки стека ошибки. Самый простой способ сделать это - заменить '(Exception e)' на '(Throwable e)'; правильный способ сделать это состоит в том, чтобы добавить второй блокирующий блок после существующего для 'catch (Error err)'. – JoshDM

ответ

1

Ваша проблема с подвеской, по-видимому, связана с вызовом readLine.

readLine предназначен для считывания строк. Метод не вернется, пока не будет уверен, что конец линии достигнут. Он ожидает либо символа новой строки, либо полного прекращения связи.

Ваша первая утилита не отправляет новый символ линии?

Не удалось ли вашей первой утилите закрыть поток?

Ваш звонок будет вешать бесконечно, если ответ на оба вопроса будет да.

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

+0

Спасибо за редактирование моего вопроса. Я в порядке с вашим первым вопросом. Невозможно понять ваш второй вопрос. Просто вырабатывая процесс: Когда я запускаю первую утилиту с помощью второй утилиты, первая утилита печатает свой собственный PID (используя Soprintln) на консоли (например, PID @ 7700). И продолжит прослушивание на порту 9090. Вторая утилита консольный вывод первой утилиты. Когда первая утилита завершается вместе с ошибкой, тогда вторая в то время как цикл утилиты Restart прерывается. Вторая утилита снова перезапустит первую утилиту. Что нужно сделать в первой утилите в соответствии с вашим вторым вопросом? – Deepak

+0

Пожалуйста, отредактируйте свой основной пост, чтобы включить захват вывода из первой утилиты. – JoshDM

+0

Являются ли данные об ошибках переданы второй утилите из первой утилиты, когда первая утилита ломается? Если нет, вам может потребоваться сделать то, что рекомендует Улага и изменить конструктор 'BufferedReader', чтобы вызвать' getErrorStream() '. – JoshDM

1

Попытайтесь использовать getErrorStream(), он поймает сообщение об ошибке, если вы используете getInputStream(), он будет читать только сообщения об успешном сообщении или сообщения обратной связи.

напр: если выполнить следующую команду & прочитать сообщение, используя процесс getInputStream(),

Process process = Runtime.getRuntime().exec("net use u: \\sharedIP\sharedFolder"); 
BufferedReader input = new BufferedReader(new inputStreamReader(process.getInputStream())); 

вы можете получить только сообщения обратной связи, как «сетевой диск, подключенный успешно», но не сообщения об ошибках.

, если вы используете getErrorStream(), чтобы прочитать сообщение о процессе, оно будет читать сообщения об ошибках типа «сетевой диск не найден». при выполнении процесса он выдает сообщение либо getInputStream(), либо getErrorStream(). поэтому используйте оба метода для чтения сообщения из процесса, если я прав, это сработает. Я просто пытаюсь дать вам идею, но я не уверен.

1

Попробуйте использовать .ready() функция.

try { 
     if (stdError.ready()) 
     { 
      while((line= stdError.readLine()) != null){ 
       logger.error(line); 
      } 
     } 
} 

Сделайте то же самое для стандартного вывода.

Это работало как очарование для меня.

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