JVM падает из-за стресса на RHEL 5.2 - PullRequest
10 голосов
/ 11 февраля 2010

У меня произошел (в настоящее время самый последний) сбой jdk 1.6.0.18 при запуске веб-приложения на (в настоящее время новейшем) tomcat 6.0.24 неожиданно после 4–24 часов 4 часов до 8 дней стресс-тестирование (30 потоков, попадающих в приложение со скоростью 6 миллионов просмотров страниц в день). Это на RHEL 5.2 (Тиканга).

Отчет о сбое: http://pastebin.com/f639a6cf1, а согласованные части сбоя:

  • SIGSEGV бросается
  • на libjvm.so
  • eden space всегда заполнен (100%)

JVM работает со следующими параметрами:

CATALINA_OPTS="-server -Xms512m -Xmx1024m -Djava.awt.headless=true"

Я также проверил память на наличие проблем с оборудованием, используя http://memtest.org/ в течение 48 часов (14 проходов всей памяти) без каких-либо ошибок.

Я включил -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps для проверки любых тенденций ГХ или исчерпания пространства, но там нет ничего подозрительного. GC и полный GC происходят с предсказуемыми интервалами, почти всегда освобождая одинаковое количество памяти.

Мое приложение напрямую не использует какой-либо нативный код.

Есть идеи, куда мне смотреть дальше?

Редактировать - больше информации :

1) В этом JDK нет клиента vm:

[foo@localhost ~]$ java -version -server
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)

[foo@localhost ~]$ java -version -client
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)

2) Смена O / S невозможна.

3) Я не хочу изменять переменные стресс-теста JMeter, так как это может скрыть проблему. Поскольку у меня есть сценарий использования (текущий сценарий стресс-теста), в котором происходит сбой JVM, я бы хотел исправить сбой, а не менять тест.

4) Я сделал статический анализ для моего приложения, но ничего серьезного не получилось.

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

6) / var / log / messages не содержит никакой полезной информации до или во время сбоя

Дополнительная информация : Забыл упомянуть, что существует tomcat apache (2.2.14), использующий mod_jk 1.2.28. Прямо сейчас я запускаю тест без Apache на тот случай, если сбой JVM связан с собственным кодом mod_jk, который подключается к JVM (соединитель Tomcat).

После этого (если JVM снова выйдет из строя) я попытаюсь удалить некоторые компоненты из моего приложения (кеширование, lucene, кварц) и позже попробую использовать jetty. Поскольку в настоящее время сбой происходит в любое время от 4 часов до 8 дней, может потребоваться много времени, чтобы выяснить, что происходит.

Ответы [ 7 ]

4 голосов
/ 01 марта 2010

У вас есть вывод компилятора? то есть PrintCompilation (и если вы чувствуете себя особенно смелым, LogCompilation).

Я отлаживал такой случай в этой части, наблюдая за тем, что делает компилятор, и, в конце концов (это заняло много времени до момента появления лампочки), осознавая, что мой сбой был вызван компиляцией определенного метода в oracle jdbc драйвер.

В основном я бы сделал;

  • включить PrintCompilation
  • , поскольку это не дает меток времени, напишите скрипт, который просматривает этот лог-файл (например, спит каждую секунду и печатает новые строки) и сообщает, когда методы были скомпилированы (или нет)
  • повторить тест
  • проверить вывод компилятора, чтобы увидеть, соответствует ли сбой компиляции какого-либо метода
  • повторите еще несколько раз, чтобы увидеть, есть ли образец

Если есть различимый шаблон, используйте .hotspot_compiler (или .hotspotrc), чтобы он прекратил компилировать вызывающий (-ые) метод (-ы), повторите тест и посмотрите, не сработает ли он. Очевидно, в вашем случае этот процесс теоретически может занять месяцы, я боюсь.

некоторые ссылки

Другая вещь, которую я бы сделал, - систематически изменяйте алгоритм gc, который вы используете и , для проверки времени сбоев по активности gc (например, соотносится ли он с молодым или старым gc, как насчет TLAB? ). Ваш дамп указывает, что вы используете параллельную очистку, поэтому попробуйте

  • серийный (молодой) коллектор (IIRC может сочетаться с параллельным старым)
  • ParNew + CMS
  • G1

если он не повторяется с другими GC-алгоритмами, то вы знаете, что дело в этом (и у вас нет другого решения, кроме как изменить GC-алгоритм и / или вернуться к старым JVM, пока не найдете версию этого алгоритма, которая не не взорвать).

3 голосов
/ 24 февраля 2010

Несколько идей:

  • Используйте другую версию JDK, Tomcat и / или ОС
  • Немного изменить параметры теста, например, 25 потоков при 7,2 млн просмотров страниц в день
  • Использование памяти монитора или профиля
  • Отладка или настройка сборщика мусора
  • Запуск статического и динамического анализа
2 голосов
/ 25 февраля 2010

Вы пробовали другое оборудование? Похоже, вы используете 64-битную архитектуру. По собственному опыту 32-битный работает быстрее и стабильнее. Возможно, есть проблема с оборудованием где-то тоже. Время "между 4-24 часами" довольно распространено, чтобы быть просто проблемой программного обеспечения. Хотя вы говорите, что в системном журнале нет ошибок, поэтому я могу быть далеко. Тем не менее думаю, стоит попробовать.

1 голос
/ 27 февраля 2010

Можно ли вместо этого перейти на 32-разрядную JVM? Я считаю, что это самое зрелое предложение от Sun.

1 голос
/ 25 февраля 2010

На вашем месте я бы сделал следующее:

  • попробуйте чуть более старые версии Tomcat / JVM. Вы, кажется, работаете самым новым и лучшим. Я бы остановился на двух версиях или около того, возможно, попробую JRockit JVM.
  • сделать дамп потока (kill -3 java_pid), пока приложение работает, чтобы увидеть полные стеки. Ваш текущий дамп показывает, что многие потоки заблокированы, но неясно, где они блокируются (ввод / вывод - некоторое внутреннее блокирование блокировки - что-нибудь еще?). Возможно, я бы даже запланировал запуск kill -3 каждую минуту, чтобы сравнить любой случайный дамп потока с тем, который был до сбоя.
  • Я видел случаи, когда Linux JDK просто умирает, тогда как Windows JDK может изящно перехватить исключение (тогда это было StackOverflowException), поэтому, если вы можете изменить код, добавьте «catch Throwable» где-то в верхнем классе. На всякий случай.
  • Играть с настройками GC. Включить / выключить одновременный сборщик мусора, настроить NewSize / MaxNewSize. И да, это не научно - скорее отчаянная потребность в рабочем решении. Подробнее здесь: http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html

Дайте нам знать, как это было решено!

1 голос
/ 25 февраля 2010

Попробуйте переключить свой контейнер сервлетов с Tomcat на Jetty http://jetty.codehaus.org/jetty/.

1 голос
/ 24 февраля 2010

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

Можете ли вы воспроизвести проблему быстрее, если:

  • Вы уменьшитепамять, доступная для JVM?
  • Вы уменьшаете доступные системные ресурсы (т. е. расходуете системную память, так что JVM не хватает)
  • Вы меняете варианты использования на более простую модель?

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

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

Удачи, Джейкоб

...