Проблемы PermGen с Lift и Jetty

Я занимаюсь разработкой на стандартной платформе 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 иметь дело с большим количеством классов?

ура

Джо

5 ответов

Решение

Из этого поста:

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

  • -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 в будущем

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам