Java кажется зависшей

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

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

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

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

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

Ответов (4)

Решение

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

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

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

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

Изменить 13.06.2017

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

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

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

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

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

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

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

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

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

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

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

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