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