Какова основная причина ошибки 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.