Назад | Перейти на главную страницу

Что вызывает PermGen OutOfMemoryError на JBoss?

Какова основная причина ошибки PermGen OutOfMemoryError в JBoss?

Я использую JBoss AS 4.2.2 в своей среде разработки, и это происходит после многократного повторного развертывания моего веб-приложения.

Блог Кристиана Веста Хансена предоставляет параметры JVM, которые помогают много, но не решают проблему полностью:

-XX:+UseConcMarkSweepGC
-XX:+CMSPermGenSweepingEnabled
-XX:+CMSClassUnloadingEnabled
-XX:MaxPermSize=128m

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

  • Объекты указанных классов все еще существуют в куче, объекты всегда ссылаются на свой класс или
  • Загрузчик классов упоминается где-то, по какой-то причине загрузчики классов ссылаются на свои классы, чтобы не загружать их дважды

У этой проблемы нет универсального решения. Один полезный инструмент, который поможет вам найти основную причину, - это Инструмент Eclipse Memory Analyzer, который вы можете применить к дампу кучи из вашей JVM (вы можете включить дампы кучи в OOM с параметром -XX: + HeapDumpOnOutOfMemoryError). Возможно, начните искать объекты java.lang.Class в своем веб-приложении, чтобы понять, почему они остаются в живых. К сожалению, PermGen обычно не является частью дампа кучи JVM, поэтому вы можете попытаться найти коррелирующие артефакты только в остальной части кучи (объекты классов не хранятся в PermGen, если я не ошибаюсь, только фактический байтовый код, пожалуйста поправьте меня, если я ошибаюсь).

HTH.

Редактировать:
Дэйв Чейни в комментарии предполагает, что объекты java.lang.Class действительно являются частью PermGen и не включены в обычный дамп кучи горячей точки. Если у вас нет JVM, которая записывает эту информацию в дамп кучи, вам понадобится другой подход. Вы все еще можете искать экземпляры своих объектов, но если вы пропускаете классы / загрузчики классов (они оба, к сожалению, подразумевают друг друга), кажется, вам нужно искать другие признаки (объекты метаданных из JBoss и т. Д.).

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

Есть хорошее, довольно сложное объяснение Вот

Причина ошибки PermGen OutOfMemory - повторное развертывание приложения. Основная причина - утечка объектов Class в PermGen при повторных развертываниях.

Конечно, обходной путь - перезапустить JVM после определенного количества повторных развертываний.

Это очень сложная проблема для полного решения, хотя при некотором поиске часто можно добиться больших улучшений. Вот с чего начать: когда ваше веб-приложение остановлено, убедитесь, что:

  • все Начатые вами темы остановлены
  • все Запущенные вами пулы потоков закрываются
  • все статические ссылки, которые вы можете выпустить, освобождаются

Это некоторые из вещей, которые могут привести к захвату объекта Class в PermGen.

Также обратите внимание, что не все JVM (или все версии JVM) будут объектами GC Class в PermGen. Если вы используете JVM или версию JVM, которая не поддерживает объекты класса GC в PermGen, то ваш единственный выбор - перезапустить JVM после определенного числа повторных развертываний. это наверное не относится к вам, учитывая указанные вами параметры JVM.