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

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

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

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

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

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


person Sarel Botha    schedule 01.03.2009    source источник


Ответы (4)


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

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

person Kevin    schedule 01.03.2009
comment
Увеличение свойства может привести к тому, что оболочка не заметит проблему и не перезапустит приложение, но это всего лишь обходной путь для решения проблемы. Во время зависания он не отвечал на запросы клиентов, что тоже нехорошо. - person Sarel Botha; 02.03.2009

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

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

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

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

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

person TofuBeer    schedule 01.03.2009
comment
Пробовал это. В прошлый раз он завис, количество потоков и объем используемой памяти были довольно низкими, поэтому ни один из них не вызывает проблемы. К сожалению, после того, как он зависнет и оболочка завершит его, вы не сможете получить дамп потока. - person Sarel Botha; 04.03.2009

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

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

person Charlie Martin    schedule 01.03.2009
comment
Linux RHEL4, Java 1.6.0, 32-разрядная версия Intel. Я слежу за количеством потоков и использованием памяти; пока он не использует много ни того, ни другого. Мы не используем потоки много. Мы просто запускаем несколько во время запуска приложения, чтобы каждые несколько минут проверять, есть ли что-то для обработки. - person Sarel Botha; 02.03.2009
comment
насколько постоянны 10 часов? На самом деле есть только пара возможностей: либо некоторое исчерпание ресурсов, либо случайный тупик/задержка. Какое приложение? - person Charlie Martin; 02.03.2009
comment
Совсем не соответствует. Пока это было только три раза. На самом деле похоже, что среднее значение немного превышает 10 часов. Это произошло в 12, 14 и 19 часов. Что я собираюсь сделать, так это отключить автоматический перезапуск, чтобы я мог немного исследовать состояние, когда это произойдет. - person Sarel Botha; 02.03.2009
comment
Хорошо, тогда это говорит о случайном событии. Вместо этого у меня возникнет соблазн установить как можно более короткий интервал проверки связи, чтобы вы могли повторить его быстрее. - person Charlie Martin; 02.03.2009
comment
Это также происходило в случайное время. У нас есть некоторые задания, работающие в фиксированное время, так что это не они. Это автономное серверное приложение Java. Он принимает вызовы RMI от клиентов. Он взаимодействует с базой данных через Hibernate. - person Sarel Botha; 02.03.2009
comment
Какая база данных? У меня были проблемы с тем, что Postgres отключался во время побочной прогулки, очищая себя и, таким образом, периодически вводя ожидание. - person Charlie Martin; 02.03.2009
comment
Это майскл. Однако это не должно вызывать проблем в процессе Java. Один поток, ожидающий ответа базы данных, не должен вешать всю JVM. - person Sarel Botha; 02.03.2009
comment
Последняя версия RHEL4? Несколько лет назад в Red Hat была ошибка, из-за которой ОС сбрасывала уведомления. - person Tom Hawtin - tackline; 02.03.2009

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

Вот статья 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-процесса.

person Sarel Botha    schedule 09.03.2009