Вопрос

Я разрабатываю на стандартной платформе 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)

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top