Проблемы PermGen с лифтом и причалом
-
12-09-2019 - |
Вопрос
Я разрабатываю на стандартной платформе Lift (maven и jetty).Постоянно (раз в пару дней) получаю вот это:
Exception in thread "7048009@qtp-3179125-12" java.lang.OutOfMemoryError: PermGen space
2009-09-15 19:41:38.629::WARN: handle failed
java.lang.OutOfMemoryError: PermGen space
Это в моей среде разработки.Это не проблема, потому что я могу продолжать перезапускать сервер.При развертывании у меня нет таких проблем, так что это не настоящая проблема.Мне просто интересно.
Я не слишком много знаю о JVM.Думаю, я прав, полагая, что постоянная память поколения предназначена для таких вещей, как классы и интернированные строки?То, что я помню, немного перепутано с моделью памяти .NET...
Есть ли причина, почему это происходит?Значения по умолчанию просто безумно низкие?Связано ли это со всеми вспомогательными объектами, которые Scala должен создавать для объектов Function и тому подобных вещей FP?Каждый раз, когда я перезапускаю Jetty с новым написанным кодом (каждые несколько минут), я представляю, что он перезагружает классы и т. д.Но даже в этом случае их не может быть так много, не так ли?И разве JVM не должна иметь дело с большим количеством классов?
Ваше здоровье
Джо
Решение
От эта почта:
Это исключение произошло по одной простой причине:
тотpermgenspace
здесь находятся свойства класса, такие как методы, поля, аннотации, а также статические переменные и т. д.хранятся в виртуальной машине Java, но особенностью этого пространства является то, что оно не очищается сборщиком мусора.Итак, если ваше веб-приложение использует или создает много классов (я имею в виду динамические поколения классов), скорее всего, вы столкнулись с этой проблемой.Вот несколько решений, которые помогли мне избавиться от этого исключения:
-XX:+CMSClassUnloadingEnabled
:этот параметр включает сбор мусора в постоянном пространстве-XX:+CMSPermGenSweepingEnabled
:позволяет сборщику мусора удалять из памяти даже классы-XX:PermSize=64M -XX:MaxPermSize=128M
:увеличивает объем памяти, выделенной для permgenspace
Может быть, это могло бы помочь.
Редактировать июль 2012 г. (почти 3 года спустя):
Ондра Жижка комментарии (и я обновил ответ выше):
JVM 1.6.0_27 говорит:Пожалуйста, используйте:
CMSClassUnloadingEnabled
(Включена ли выгрузка классов при использовании CMS GC)- на месте
CMSPermGenSweepingEnabled
в будущем
Посмотреть полную версию Параметры JVM Hotspot — полный справочник для мрое.
Другие советы
Если вы видите это во время работы mvn jetty:run
, установить MAVEN_OPTS
.
Для Linux:
export MAVEN_OPTS="-XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M"
mvn jetty:run
Для Windows:
set "MAVEN_OPTS=-XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M"
mvn jetty:run
Теперь все должно быть в порядке.Если нет, увеличьте -XX:MaxPermSize
.
Вы также можете поместить их навсегда в свою среду.
Для Linux добавьте
export
линия к~/.bashrc
Для Windows нажмите
Win-key + PrintScreen
, и идиAdvanced > Environment
.Смотрите также http://support.microsoft.com/kb/310519.
Это из-за перезагрузки классов, как вы предложили.Если вы используете много библиотек и т.д.сумма классов будет быстро расти при каждом перезапуске.Попробуйте отслеживать экземпляр причала с помощью VisualVM, чтобы получить обзор потребления памяти при перезагрузке.
Список рассылки (http://groups.google.com/group/liftweb/) — официальный форум поддержки Lift, где вы сможете получить лучший ответ.Я не знаю подробностей вашей настройки разработки (вы не вдаетесь в подробности), но я предполагаю, что вы перезагружаете свою войну в Jetty, фактически не перезапуская ее.Lift не выполняет динамическую генерацию классов (как было предложено VonC выше), но Scala компилирует каждое замыкание как отдельный класс.Если вы добавляете и удаляете замыкания в свой код в течение нескольких дней, возможно, слишком много классов загружаются и никогда не выгружаются и занимают постоянное пространство.Я бы посоветовал вам включить параметры JVM, упомянутые VonC выше, и посмотреть, помогут ли они.
Постоянное поколение — это то, куда JVM помещает вещи, которые, вероятно, не будут собираться (мусор), как пользовательские загрузчики классов.
В зависимости от того, что вы развертываете, параметр Perm Gen может быть низким.Некоторые комбинации приложений и/или контейнеров содержат некоторые утечки памяти, поэтому, когда приложение не развертывается, иногда некоторые вещи, такие как загрузчики классов, не собираются, что приводит к заполнению Perm Space, что приводит к возникновению вашей ошибки.
К сожалению, в настоящее время лучшим вариантом в этом случае является максимальное увеличение постоянного пространства с помощью следующего флага jvm (пример для размера постоянного пространства 192 м):
-XX:MaxPermSize=192M (or 256M)
Другой вариант — убедиться, что ни контейнер, ни платформа не вызывают утечку памяти.