Подтвердить что ты не робот

Проблемы PermGen с подъемником и причалом

Я развиваюсь на стандартной платформе Lift (maven и причал). Я неоднократно (раз в пару дней) получаю следующее:

Exception in thread "[email protected]" java.lang.OutOfMemoryError: PermGen space
2009-09-15 19:41:38.629::WARN:  handle failed
java.lang.OutOfMemoryError: PermGen space

Это в моей среде dev. Это не проблема, потому что я могу продолжать перезагружать сервер. В развертывании у меня таких проблем нет, так что это не настоящая проблема. Мне просто интересно.

Я не слишком много знаю о JVM. Думаю, я прав, думая, что память постоянного поколения для таких вещей, как классы и интернированные строки? То, что я помню, немного смешано с моделью памяти .NET...

Любая причина, почему это происходит? Являются ли дефолты просто безумно низкими? Это связано со всеми вспомогательными объектами, которые Scala должен создавать для объектов Function и подобных FP-вещей? Каждый раз, когда я перезапускаю Jetty с новым кодом (каждые несколько минут), я предполагаю, что он перезагружает классы и т.д. Но даже в этом случае не может быть так много? И не должна ли JVM иметь дело с большим количеством классов?

Приветствия

Джо

4b9b3361

Ответ 1

От этот пост:

Это исключение произошло по одной простой причине:
permgenspace, где свойства класса, такие как методы, поля, аннотации, а также статические переменные и т.д. хранятся в виртуальной машине Java, но это пространство имеет особенность не очищаться с помощью уборщик мусора. Поэтому, если ваш webapp использует или создает много классов (Im думает о динамических поколениях классов), скорее всего, вы столкнулись с этой проблемой. Вот некоторые решения, которые помогли мне избавиться от этого исключения:

  • -XX:+CMSClassUnloadingEnabled: этот параметр позволяет сборку мусора в permgenspace
  • -XX:+CMSPermGenSweepingEnabled: позволяет сборщику мусора удалить даже классы из памяти
  • -XX:PermSize=64M -XX:MaxPermSize=128M: увеличивает объем памяти, выделенной для permgenspace

Возможно, это поможет.

Редактировать Июль 2012 (почти 3 года спустя):

Комментарии Ondra Žižka (и я обновил ответ выше):

JVM 1.6.0_27 говорит: Пожалуйста, используйте:

  • CMSClassUnloadingEnabled (Разрешена ли разгрузка классов при использовании CMS GC)
  • вместо CMSPermGenSweepingEnabled в будущем

См. полный Параметры JVM Hotspot - полная ссылка для mroe.

Ответ 2

Если вы видите это при запуске 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.

Ответ 3

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

Ответ 4

Список рассылки (http://groups.google.com/group/liftweb/) является официальным форумом поддержки для Lift, и где вы сможете получить лучшее ответ. Я не знаю подробностей вашей установки dev (вы не вникаете в детали), но я предполагаю, что вы перезагружаете свою войну в Jetty, не перезапуская ее. Подъем не выполняет динамическое генерирование классов (как предложено VonC выше), но Scala компилирует каждое закрытие как отдельный класс. Если вы добавляете и удаляете замыкания на свой код в течение нескольких дней, возможно, что слишком много классов загружаются и никогда не выгружаются и не занимают перманентное пространство. Я предлагаю вам включить опции JVM, упомянутые выше VonC, и посмотреть, помогают ли они.

Ответ 5

Постоянное поколение - это то, где JVM помещает материал, который, вероятно, не будет (мусор), собранным как пользовательские загрузчики классов.

В зависимости от того, что вы развертываете, настройка perm gen может быть низкой. Некоторые комбинации приложений и/или контейнеров содержат некоторые утечки памяти, поэтому, когда приложение становится незадействованным, иногда некоторые вещи, такие как загрузчики классов, не собираются, что приводит к заполнению Perm Space, создавая при этом вашу ошибку.

К сожалению, в настоящее время лучшим вариантом в этом случае является максимальное увеличение пространства perm со следующим флагом jvm (пример для размерного размера 192 м):

-XX:MaxPermSize=192M (or 256M)

Другой вариант заключается в том, чтобы убедиться, что контейнер или инфраструктура не утечка памяти.