Ошибка OutOfMemory JVM "спираль смерти" (не утечка памяти) - PullRequest
19 голосов
/ 19 февраля 2010

Недавно мы перенесли несколько приложений из RedHat linux JDK1.6.0_03 в Solaris 10u8 JDK1.6.0_16 (машины с более высокими характеристиками), и мы заметили, что кажется довольно насущной проблемой: при определенных нагрузках наши JVM попадают в «Спираль Смерти» и со временем выходят из памяти. На что обратить внимание:

  • это не случай утечки памяти . Это приложения, которые работали очень хорошо (в одном случае более 3 лет), и ошибки нехватки памяти не гарантированы в любом случае. Иногда приложения работают, иногда они не
  • это мы не переходим на 64-битную виртуальную машину - у нас все еще работает 32-битная
  • В одном случае использование последней сборки мусора G1 на 1.6.0_18, похоже, решило проблему. В другом переход на 1.6.0_03 сработал
  • Иногда наши приложения падают с HotSpot SIGSEGV ошибки
  • Это влияет на приложения, написанные на Java, а также на Scala

Наиболее важный момент заключается в следующем: поведение проявляется в тех приложениях, которые внезапно получают поток данных (обычно через TCP) . Как будто виртуальная машина решает продолжать добавлять больше данных (возможно, прогрессируя их в TG), а не запускать GC в «газетах», пока не осознает, что должна выполнить полный GC, а затем , несмотря на то, что практически все в ВМ, будучи мусором, почему-то решает не собирать ее!

Звучит безумно, но я просто не вижу, что это еще. Как еще можно объяснить приложению, у которого одна минута падает с максимальной кучей в 1 Гб, а следующая работает просто отлично (никогда не бывает около 256 Мб, когда приложение делает то же самое )

Итак, мои вопросы:

  1. Кто-нибудь еще наблюдал такое поведение?
  2. есть ли у кого-нибудь предложения относительно того, как я могу отлаживать саму JVM (в отличие от моего приложения)? Как мне доказать, что это проблема с виртуальной машиной?
  3. Существуют ли форумы для специалистов по ВМ, где я могу задать вопрос авторам ВМ (при условии, что они не на SO)? (У нас нет контракта на поддержку)
  4. Если это ошибка в последних версиях ВМ, почему никто не заметил ее?

Ответы [ 6 ]

2 голосов
/ 19 февраля 2010

Интересная проблема. Похоже, один из сборщиков мусора плохо работает в вашей конкретной ситуации.

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

Я знаю, что есть GC «Сервер», который работает намного лучше, чем стандартные. Вы используете это?

Резьбовой ГХ (который, я считаю, используется по умолчанию), вероятно, является худшим для вашей конкретной ситуации, я заметил, что он обычно менее агрессивен, когда машина занята.

Одна вещь, которую я заметил, часто требуется два сборщика мусора, чтобы убедить Java действительно вынести мусор. Я думаю, что первый имеет тенденцию разъединять кучу объектов, а второй фактически удаляет их. То, что вы, возможно, захотите сделать, - это вызвать две сборки мусора. Это вызовет значительную паузу в GC, но я никогда не видел случая, чтобы очистка всей кучи заняла более двух.

2 голосов
/ 19 февраля 2010
  1. Да, я наблюдал это поведение раньше, и обычно после бесчисленных часов настройки параметров JVM оно начинает работать.
  2. Сборка мусора, особенно в многопоточных ситуациях, недетерминирована.Определение ошибки в недетерминированном коде может быть проблемой.Но вы можете попробовать DTrace, если вы используете Solaris, и есть много вариантов JVM для вглядывания в HotSpot.
  3. Перейдите на Scala IRC и посмотрите, не торчит ли Исмаэль Джума (ijuma).Он помогал мне раньше, но я думаю, что настоящая всесторонняя помощь требует оплаты за нее.
  4. Я думаю, что большинство людей, занимающихся подобными вещами, признают, что им либо нужно быть специалистами по настройке JVM, либо иметь одного в штате, либонанять консультанта.Есть люди, которые специализируются на настройке JVM.

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

2 голосов
/ 19 февраля 2010

У меня была такая же проблема на машинах Solaris, и я решил ее, уменьшив максимальный размер JVM.32-битная реализация Solaris, очевидно, нуждается в некотором дополнительном пространстве, помимо того, которое вы выделяете для JVM при выполнении сборки мусора.Так, например, с -Xmx3580M я получу описанные вами ошибки, но с -Xmx3072M все будет в порядке.

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

С какими именно ошибками SIGSEV вы сталкиваетесь?

Если вы используете 32-битную виртуальную машину, это может быть то, что я описал здесь:

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

Также убедитесь, что это не аппаратная ошибка (попробуйте запустить MemTest86 или аналогичный на сервере.)

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

Какой вид OutOfMemoryError вы получаете?Исчерпано ли пространство кучи или проблема связана с любым из других пулов памяти (в сообщении об ошибке обычно указывается более подробная информация о его причине).

Если куча исчерпана и проблема может быть воспроизведена (это звучит так, как будто это возможно), я бы прежде всего настроил виртуальную машину для создания дамп кучи на OutOfMemoryErrors.Затем вы можете проанализировать кучу и убедиться, что она не заполнена объектами, которые все еще доступны через некоторые неожиданные ссылки.

Конечно, не исключено, что вы сталкиваетесь с ошибкой ВМ, но если ваше приложениеполагаясь на специфическое для реализации поведение в 1.6.0_03, оно может по тем или иным причинам стать бродягой памяти при работе на 1.6.0_16.Такие проблемы также могут быть обнаружены, если вы используете какой-либо серверный контейнер для своего приложения.Некоторые разработчики, очевидно, не могут читать документацию, но, как правило, наблюдают за поведением API и делают собственные выводы о том, как что-то должно работать.Это, конечно, не всегда правильно, и я столкнулся с похожими проблемами как с Tomcat, так и с JBoss (оба продукта, по крайней мере, раньше работали только с определенными виртуальными машинами).

...