Проблемы PermGen с лифтом и молой - PullRequest
41 голосов
/ 20 сентября 2009

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

44 голосов
/ 20 сентября 2009

С этот пост :

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

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

Может быть, это может помочь.

Редактировать июль 2012 г. (почти через 3 года):

Ондра Жижка комментариев (и я обновил ответ выше):

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

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

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

12 голосов
/ 23 июля 2012

Если вы видите это при запуске 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 голосов
/ 22 сентября 2010

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

2 голосов
/ 20 сентября 2009

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

1 голос
/ 20 сентября 2009

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...