Jetty 7: OutOfMemoryError: пространство PermGen при повторном развертывании приложения

Первое время приложение запускается правильно. Затем я удаляю файл webapp/*. War и вставляю новую версию *.war. Причал начинает развертывание новой войны, но ошибка java.lang.OutOfMemoryError: PermGen space происходит. Как я могу настроить Jetty, чтобы исправить ошибку / сделать правильное повторное развертывание?

Это решение не помогает мне.
Версия для причала: jetty-7.4.3.v20110701

6 ответов

Вероятно, нет способа устранить проблему. Каждая JVM имеет одну область памяти PermGen, которая используется для загрузки классов и статических данных. Всякий раз, когда ваше приложение отменяется, его загрузчик классов следует отбрасывать, а также загружать все классы. Если это не удается из-за того, что другие ссылки на загрузчик классов все еще существуют, сборщик мусора и классы ваших приложений также не будут работать.

Запись в блоге и ее продолжение объясняют возможный источник проблемы. Всякий раз, когда код контейнера приложения использует класс, который содержит ссылку на один из ваших классов, сборка мусора ваших классов запрещается. Пример из упомянутой записи в блоге java.util.logging.Level конструктор:

protected Level(String name, int value) {
    this.name = name;
    this.value = value;
    synchronized (Level.class) {
        known.add(this);
    }
}

Обратите внимание, что known является статическим членом java.util.logging.Level, Конструктор хранит ссылку на все созданные экземпляры. Так что, как только Level класс был загружен или создан из кода вашего приложения, сборщик мусора не может удалить ваши классы.

Чтобы решить эту проблему, вы можете избежать использования всех классов, которые используются в вашем собственном коде, или обеспечить отсутствие ссылок на ваши классы из вашего кода. Обе проблемы могут возникать в любом классе, поставляемом с Java, и поэтому их невозможно исправить в вашем приложении. Вы не можете предотвратить проблему, изменяя только свой собственный код!

Ваши варианты в основном:

  • Увеличение пределов памяти и ошибка реже
  • Проанализируйте свой код, как подробно описано в связанных сообщениях блога, и избегайте использования классов, которые хранят ссылки на ваши объекты

Если у PermGen недостаточно памяти, вам нужно перезапустить jvm, в вашем случае перезапустить Jetty. Вы можете увеличить пространство PermGen с помощью опций JVM в связанном решении, так что это произойдет позже (я имею в виду позже: после повторных развертываний). Но это случается время от времени, и вы ничего не можете сделать, чтобы избежать этого. Ответ, который вы связали, хорошо объяснил, что такое PermGenSpace и почему он переполнен.

Использование:

-XX:PermSize=64M -XX:MaxPermSize=128M

или, если этого еще недостаточно

-XX:PermSize=256M -XX:MaxPermSize=512M

Кроме того, не забудьте увеличить объем пространства, доступного для виртуальной машины в целом, если вы используете эти команды.

использование

-Xms128M -Xmx256M

Для Jetty 7.6.6 или более поздней версии это может помочь http://www.eclipse.org/jetty/documentation/current/preventing-memory-leaks.html.

Мы использовали AppContextLeakPreventer и это помогло с ошибками OOM из-за пространства permgen

Для читателей будущего (относительно того, когда был задан этот вопрос):

В JDK 8 Пермское Генеральное Пространство исчезло (больше не существует). Вместо этого теперь есть Metaspace, который взят из собственного пространства машины.

Если у вас возникли проблемы с Perm Gen Overflow, возможно, вы захотите взглянуть на это объяснение и комментарии к процессу удаления.

У меня та же проблема с HotSpot, но с JRockit, который не имеет постоянного поколения, проблема ушла. Это бесплатно сейчас, так что вы можете попробовать это: https://blogs.oracle.com/henrik/entry/jrockit_is_now_free_and

Очень похоже на утечку из постоянного поколения. Всякий раз, когда ваше приложение оставляло некоторые классы после того, как оно было развернуто, вы получаете эту проблему. Вы можете попробовать последнюю версию Plumbr, возможно, она найдет оставшиеся классы.

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