Устранение неполадок в процессе Java с очень высокой загрузкой процессора - приложение Tomcat - PullRequest
3 голосов
/ 12 августа 2011

У меня есть Java-приложение, которое работает на Tomcat (которое работает как служба в Windows), процесс Java, для которого продолжает загружаться процессор, прежде чем в конечном итоге потребовать от меня перезапустить службу Tomcat.

Сначала мои настройки: Windows 2003 сервер Tomcat 6, работающий как сервис с использованием Wrapper JDK: 1.6.0_20

Я видел проблемы с уловом тут и там до вчерашнего дня. Вчера мне пришлось перезапустить полдень, а затем в 2:30 утра, а сегодня я едва мог перезапустить приложение и открыть jconsole для мониторинга, прежде чем оно снова достигнет 99% загрузки ЦП. Из-за комбинации вещей, в которых я не совсем уверен, кажется, что я заставил JVM зацикливаться, и приложение зависало в диапазоне использования ЦП 10-30% в течение пары часов. Тем не менее, затем он снова начал набирать скорость, в конечном итоге перешел на 99% -ную нагрузку на процессор. У меня также были проблемы с высоким использованием памяти, но это оставалось довольно нормальным и стабильным, так как я так называемую заставил JVM «зацикливаться» (возможно, плохая терминология, но это действительно то, что казалось, - и в журнале обертки был дамп всех классов, после которых он перезагружался).

Потом я еще немного покопался и обнаружил, что на сервере установлено обновление 24 для JRE 6 (я его не устанавливал, так как проводил тщательное тестирование с каждым обновлением java, но, возможно, это сделал мой администратор сервера). Я попытался, но не могу удалить это. Таким образом, я получаю разные версии, когда делаю java -version против javac -version

java -version
    java version "1.6.0_24"
    Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
    Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)

javac -version
    javac 1.6.0_20

Может ли это различие быть причиной конфликта JVM? JAVA_HOME и мои переменные PATH указывают на правильную установку JDK.

Надеясь на большую стабильность, я решил изменить свое приложение для запуска на предыдущем JDK, который все еще был установлен - JDK 1.6.0_04. Я изменил wrapper.conf, установил переменные env, очистил и перестроил, и начал. Это кажется более стабильным и работает около 4 часов. Загрузка ЦП возросла до 90-х годов, а затем, похоже, снова проясняется.

Я сделал heapdumps, затем провел их через анализатор памяти в Eclipse (ничего нового там не нашел), я использовал jconsole с jtop для просмотра потоков - ничего не выпрыгивает, поэтому я продолжаю любопытствовать, если это Java / JVM выпуск. Итак, я знаю, что это длинный пост, но я не знаю, куда идти отсюда. Есть идеи?

(Я провел исчерпывающий поиск в Интернете по этому вопросу, и в некоторых статьях указывалось, что, возможно, проблема с Quartz или запросы Hibernate не сбрасываются. В приложении ничего не изменилось с тех пор, как я начал видеть проблемы с процессором, поэтому не уверен, где начать устранение неполадок, если оно действительно может быть связано с любым из них.)

1 Ответ

2 голосов
/ 12 августа 2011

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

Я знаю, что вы провели некоторое наблюдение за jconsole, но я думаю, что вам нужно пересмотреть и посмотреть использование вашей памяти, время выполнения потоков, сколько времени вы проводите в GC, и посмотреть, какие части памяти потребляются вверх (это Иден, срок владения истощается?).

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

Вероятно, пришло время поместить его в профилировщик (вместо jconsole), чтобы вы могли видеть, где в коде он тратит время или что взрывает память. Настоящий профилировщик позволит вам увидеть все эти данные, смешанные в вашем коде и классах. Мой фаворит - JProfiler, но YourKit тоже хорош. Вы можете получить пробную версию на 7–30 дней, чтобы у вас было достаточно времени для профилирования и выяснения вашей проблемы без необходимости ее покупки.

Начните это рано утром, так что, надеюсь, вы увидите что-нибудь рано ночью.

...