Ява кажется зависшей - PullRequest
6 голосов
/ 02 марта 2009

Я уже давно использую оболочку Java Service в пользовательских приложениях, и она работает нормально. После обновления нашего приложения до новой версии в последние несколько дней JVM начала зависать, а затем обертка печатает это в журнале: JVM зависает: время ожидания сигнала от JVM истекло.

Затем он автоматически завершает работу JVM и снова запускает приложение. Это происходит после 10 часов работы, что затрудняет отладку.

Конечно, я собираюсь просмотреть изменения, которые мы внесли, но никаких серьезных изменений не было внесено, что, я подозреваю, вызывает такие проблемы.

Где я могу посмотреть, чтобы попытаться выяснить, что происходит? Отладочные сообщения из приложения не показывают ничего интересного. Если JVM просто выходит из строя, он обычно создает дамп, который может помочь в его отладке, но он зависает, поэтому он не создает дамп. Если я сделаю так, чтобы служба не перезапускалась автоматически, могу ли я что-нибудь сделать, чтобы получить полезную информацию из JVM перед ее перезапуском?

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

Ответы [ 4 ]

9 голосов
/ 02 марта 2009

Читайте о свойство wrapper.ping.timeout . Программное обеспечение обертки время от времени связывается с вашей JVM, чтобы убедиться, что оно живое. Если по какой-либо причине это соединение не удается, оболочка считает процесс зависшим и пытается перезапустить его.

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

2 голосов
/ 02 марта 2009

Посмотрите, можете ли вы использовать Visual VM , чтобы увидеть, что происходит. Пусть VM VM постоянно следит за приложением, и когда оно перестает работать, возможно, вы сможете определить, что не так.

Если виртуальная машина зависает, вы можете получить состояние потоков ... Я думаю, что Visual VM сделает это немного проще, учитывая ваши настройки, чем обычный ctrl-break (или какой бы ни был ключевой комбо).

(Редактировать на основании комментария)

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

Есть ли способ запустить его без оболочки для его отладки? Кроме того, если вы используете профилировщик NetBeans, он может дать вам возможность справиться с ним, когда он остановится (я проверю позже сегодня и посмотрю, смогу ли я узнать, будет ли это вести себя иначе).

1 голос
/ 09 марта 2009

У меня было несколько разных версий библиотеки на пути к классам (JBPM). С оберткой вы можете использовать подстановочные знаки, чтобы включить банки. Будьте осторожны с этим, поскольку вы можете случайно включить больше, чем должны.

Вот статья IBM, в которой содержится информация о зависаниях отладки в Java . В основном это говорит о том, что есть две вещи, которые могут вызвать зависания:

  1. Бесконечный цикл,
  2. тупик.

С тех пор мне приходилось отлаживать другие зависающие проблемы. В linux вы можете отправить JVM сигнал QUIT, чтобы заставить его делать дамп потока на консоль. Это действительно помогает выяснить, где проблема. Для этого используйте эту команду: kill -QUIT

Изменить 6/13/2017

В эти дни я использую jmap, включенный в JDK, чтобы выгрузить всю память программы. Затем я использую Eclipse Memory Analyzer, чтобы увидеть точное состояние программы при ее сбое. Вы можете посмотреть список активных потоков, а затем проверить переменные в каждом кадре стека.

/usr/java/latest/bin/jmap -dump:file=/tmp/app-crash.hprof <PID>

Где PID - это идентификатор процесса Java.

1 голос
/ 02 марта 2009

В какой среде вы находитесь? ОС, версия JVM, аппаратная архитектура?

Это звучит как ошибка, и, учитывая, что это занимает много часов, звучит как ошибка исчерпания ресурса.

...