Странное поведение сборки мусора с Websphere Portal Server - PullRequest
4 голосов
/ 03 апреля 2009

Мы запускаем довольно сложное приложение в виде портлета на Websphere Portal Server 5.1 в AIX с использованием IBM JDK 1.4.2. В нашей производственной системе я вижу странное поведение в подробных журналах GC. После периода нормального поведения система может начать быстро распределять все большие и большие блоки. Система начинает тратить> 1000 мс на завершение каждого GC, но блоки распределяются так быстро, что между ошибками выделения остается только 30 мс.

  • Каждый сбой выделения немного больше последнего на некоторое целое число x 1024 байта. Например. у вас может быть 5 МБ, а затем немного позже 5 МБ + 17 * 1024.
  • Это может продолжаться до 10 минут.
  • Размер блоков увеличивается до 8–14 МБ, прежде чем он останавливается.
  • Это четырехъядерная система, и я полагаю, что сейчас она тратит> 95% своего времени на сборку GC с тремя ядрами, ожидающими, пока другое ядро ​​завершит сборку GC. На 10 минут. Уч.
  • Очевидно, что производительность системы в этот момент снижается.
  • У нас есть JSF, Hibernate & JDBC, вызовы веб-сервисов, вывод log4j и многое другое.

Я понимаю, что это скорее инфраструктурный, нежели код нашего приложения. Если бы это была плохая конкатенация строк внутри цикла, мы ожидали бы более нерегулярный рост, чем блоки 1024. Если бы это был рост StringBuffer или ArrayList, мы увидели бы удвоение размеров блоков. Этот рост заставляет меня думать о буферизации журналов или о чем-то еще. Я ничего не могу придумать в нашем приложении, чтобы было выделено даже 1 МБ, не говоря уже о 14. Сегодня я искал резервное копирование в памяти, прежде чем записывать его на диск, но объем операторов записи за этот период перебора GC был далеко не диапазон МБ.

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

Есть идеи, что может быть причиной всего этого, когда система находится под нагрузкой? Кто-нибудь видел что-нибудь подобное с Portal Server?

Примечание: для всех, кому это интересно, начинает казаться, что причиной является случайный, но огромный запрос к базе данных. Похоже, виновником является либо Hibernate, либо драйвер JDBC.

Ответы [ 3 ]

2 голосов
/ 03 апреля 2009

Не уверен, что может вызвать проблему, но вот идея о том, как исследовать больше: IBM JDK великолепен тем, что его можно настроить на создание дампа кучи при получении сигнала SIGQUIT.
В предыдущем проекте это был не наш JDK, но мы использовали его всякий раз, когда у нас возникали проблемы с памятью для расследования.

Вот как включить heapdump: http://publib.boulder.ibm.com/infocenter/javasdk/v1r4m2/index.jsp?topic=/com.ibm.java.doc.diagnostics.142j9/html/enabling_a_heapdump.html

Тогда есть инструмент под названием heaproot, который позволит вам увидеть, что находится в этих дампах.

Поиск типа объектов должен привести вас к виновнику.

1 голос
/ 24 мая 2009

В зависимости от конкретной версии IBM JDK, которую вы используете, существуют различные опции для отслеживания «больших выделений». Различия заключаются, главным образом, в реализации, и в результате получается трассировка стека Java в журнале, когда выполняется выделение определенного размера (что должно помочь вам отследить виновника).

"Суверен" 1.4.2 SR4 +: http://www -01.ibm.com / поддержка / docview.wss? UID = swg21236523

"J9" 1.4.2 (если Java работает под опцией -Xj9): Вам нужно приобрести агента JVMPI / JVMTI для той же цели, сейчас я не могу найти ссылку для этого.

0 голосов
/ 03 апреля 2009

Только подсказка ... как только у нас появился проект, который столкнулся с серьезными проблемами GC (Websphere и IBM JDK) из-за фрагментации кучи. В конце мы добавили переключатель JDK для принудительного сжатия кучи.

Sun JDK не имеет фрагментированной кучи, но IBM JDK делает это из-за разной обработки памяти / GC.

Просто попробуй ... Я не могу вспомнить магический переключатель.

...