Это проблема, которую я пытаюсь отследить уже пару месяцев. У меня запущено java-приложение, которое обрабатывает xml-каналы и сохраняет результат в базе данных. Периодически возникали проблемы с ресурсами, которые очень трудно отследить.
Предыстория: в производственном ящике (где проблема наиболее заметна) у меня нет особенно хорошего доступа к ящику, и я не смог запустить Jprofiler. Это 64-битный четырехъядерный компьютер объемом 8 ГБ, работающий под управлением centos 5.2, tomcat6 и java 1.6.0.11. Все начинается с этих java-оптов
JAVA_OPTS="-server -Xmx5g -Xms4g -Xss256k -XX:MaxPermSize=256m -XX:+PrintGCDetails -
XX:+PrintGCTimeStamps -XX:+UseConcMarkSweepGC -XX:+PrintTenuringDistribution -XX:+UseParNewGC"
Стек технологий следующий:
- Centos, 64-разрядная версия 5.2
- Java 6u11
- Tomcat 6
- Весна / WebMVC 2.5
- Гибернация 3
- Кварц 1.6.1
- DBCP 1.2.1
- MySQL 5.0.45
- Ehcache 1.5.0
- (и, конечно же, множество других зависимостей, в частности библиотеки jakarta-commons)
Ближе всего к воспроизведению проблемы я могу подойти к 32-битной машине с меньшими требованиями к памяти. Это я контролирую. Я исследовал это до смерти с помощью JProfiler и исправил многие проблемы с производительностью (проблемы с синхронизацией, предварительная компиляция / кеширование запросов xpath, сокращение пула потоков и удаление ненужной предварительной выборки гибернации, а также чрезмерное «нагревание кеша» во время обработки).
В каждом случае профилировщик показывал, что они занимают огромное количество ресурсов по той или иной причине и что после внесения изменений они перестали быть основными потребителями ресурсов.
Проблема: кажется, что JVM полностью игнорирует настройки использования памяти, заполняет всю память и перестает отвечать. Это проблема для клиента, который ожидает регулярного опроса (5-минутный базис и 1-минутный повтор), а также для наших операционных групп, которые постоянно получают уведомления о том, что ящик перестал отвечать, и должны его перезапустить. На этом ящике больше ничего значительного нет.
Проблема возникает как вывоз мусора. Мы используем сборщик ConcurrentMarkSweep (как указано выше), потому что исходный сборщик STW вызывал тайм-ауты JDBC и становился все более медленным. Журналы показывают, что по мере увеличения использования памяти это начинает вызывать сбои cms и возвращается к исходному сборщику остановки мира, который затем, кажется, не собирает должным образом.
Однако при работе с jprofiler кнопка «Run GC», кажется, хорошо очищает память, а не показывает увеличивающуюся площадь, но, поскольку я не могу подключить jprofiler напрямую к производственной коробке, и разрешение проверенных горячих точек, похоже, не работает, я остался с вуду настройки слепой сборки мусора.
Что я пробовал:
- Профилирование и устранение горячих точек.
- Использование сборщиков мусора STW, Parallel и CMS.
- Работа с минимальным / максимальным размером кучи с шагом 1 / 2,2 / 4,4 / 5,6 / 6.
- Запуск с постоянным пространством с шагом 256 МБ до 1 ГБ.
- Множество комбинаций вышеперечисленного.
- Я также проконсультировался с JVM [справочник по настройке] (http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html), но не могу найти ничего, объясняющего это поведение или каких-либо примеров _which_ настройки параметры для использования в такой ситуации.
- Я также (безуспешно) попробовал jprofiler в автономном режиме, подключившись к jconsole, visualvm, но я не могу найти ничего, что могло бы интерпретировать мои данные журнала gc.
К сожалению, проблема также возникает спорадически, она кажется непредсказуемой, может работать в течение нескольких дней или даже недели без каких-либо проблем, или она может выходить из строя 40 раз в день, и единственное, что я могу постоянно улавливать, это эта сборка мусора действует.
Может ли кто-нибудь дать какой-либо совет относительно:
a) Почему JVM использует 8 физических гигабайт и 2 ГБ пространства подкачки, когда он настроен на максимальное значение менее 6.
b) Ссылка на настройку GC, которая фактически объясняет или дает разумные примеры о том, когда и с какими настройками использовать расширенные коллекции.
c) Ссылка на наиболее распространенные утечки памяти Java (я понимаю невостребованные ссылки, но я имею в виду на уровне библиотеки / фреймворка или что-то еще в структурах данных, таких как хэш-карты).
Спасибо за любую информацию, которую вы можете предоставить.
ИЗМЕНИТЬ
Эмиль Х:
1) Да, мой кластер разработки является зеркалом производственных данных, вплоть до медиа-сервера. Основное отличие - это 32/64 бит и объем доступной оперативной памяти, который я не могу легко воспроизвести, но код, запросы и настройки идентичны.
2) Есть некоторый унаследованный код, который полагается на JaxB, но при переупорядочении заданий, чтобы попытаться избежать конфликтов планирования, это выполнение обычно исключается, поскольку оно выполняется один раз в день. Основной синтаксический анализатор использует запросы XPath, которые вызывают пакет java.xml.xpath. Это было источником нескольких горячих точек, для одного запросы не были предварительно скомпилированы, а для двух ссылки на них были в жестко запрограммированных строках. Я создал потокобезопасный кеш (hashmap) и выделил ссылки на запросы xpath как окончательные статические строки, что значительно снизило потребление ресурсов. Запросы по-прежнему являются значительной частью обработки, но это должно быть так, потому что это основная ответственность приложения.
3) Дополнительное примечание, другим основным потребителем являются операции с изображениями из JAI (повторная обработка изображений из канала). Я не знаком с графическими библиотеками Java, но из того, что я обнаружил, они не особо протекают.
(спасибо за ответы, ребята!)
ОБНОВЛЕНИЕ:
мне удалось подключиться к производственному экземпляру с помощью VisualVM, но он отключил параметр визуализации GC / run-GC (хотя я мог просматривать его локально). Интересная вещь: распределение кучи виртуальной машины подчиняется JAVA_OPTS, а фактическая выделенная куча удобно расположена на 1-1,5 гигабайт и, похоже, не протекает, но мониторинг уровня коробки все еще показывает образец утечки, но это не отражается в мониторинге ВМ. На этом ящике больше ничего не работает, поэтому я в тупике.