Tomcat на производственном сервере, PermGen и перераспределяет

Это выглядит как

 MemoryError: PermGen space
 java.lang.OutOfMemoryError: PermGen space

это общая проблема. Вы можете увеличить размер своего пермского пространства, но после 100 или 200 перераспределений оно будет заполнено. Отслеживание утечек памяти в ClassLoader практически невозможно.

Какие у вас методы для Tomcat (или другого простого контейнера сервлетов - Jetty?) На рабочем сервере? Перезапускается ли сервер после каждого развертывания решения?

Вы используете один Tomcat для многих приложений?

Может быть, мне следует использовать много серверов Jetty на разных портах (или встроенный Jetty) и каждый раз отменять / перезапускать / развертывать?

7 ответов

Решение

Я отказался от использования менеджера Tomcat и теперь всегда отключаю Tomcat для повторного развертывания.

Мы запускаем два кота на одном сервере и используем веб-сервер apache с mod_proxy_ajp, чтобы пользователи могли получить доступ к обоим приложениям через один и тот же порт 80. Это хорошо также потому, что пользователи видят страницу недоступности сервиса apache, когда кот не работает.

Вы можете попробовать добавить эти опции Java:

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

Это включает сборку мусора в пространстве PermGen (по умолчанию отключено) и позволяет GC выгружать классы. Кроме того, вы должны использовать -XX:PermSize=64m -XX:MaxPermSize=128m, упомянутые в другом месте, чтобы увеличить количество доступного PermGen.

Да, действительно, это проблема. Мы запускаем три веб-приложения на сервере Tomcat: № 1 использует среду веб-приложений, Hibernate и многие другие JAR-файлы, нет. 2 использует Hibernate и несколько JAR-ов и нет. 3 в основном очень простое приложение JSP.

Когда мы развернем нет. 1, мы всегда перезагружаем Tomcat. В противном случае космическая ошибка PermGen скоро укусит нас. № 2 иногда можно развернуть без проблем, но так как он часто меняется, когда нет. 1 также, перезапуск запланирован в любом случае. № 3 не создает никаких проблем и может быть развернут настолько часто, насколько это необходимо, без проблем.

Так что, да, мы обычно перезапускаем Tomcat. Но мы также с нетерпением ждем Tomcat 7, который должен решать многие проблемы с загрузкой памяти / классов, которые скрыты в различных сторонних JAR и средах.

Переключатели PermGen в HotSpot только задерживают проблему, и в конечном итоге вы все равно получите OutOfMemoryError.

У нас была эта проблема долгое время, и единственное решение, которое я нашел до сих пор, - использовать вместо этого JRockit. У него нет PermGen, поэтому проблема просто исчезает. Сейчас мы оцениваем его на наших тестовых серверах, и с момента переключения у нас не было ни одной проблемы с PermGen. Я также попытался переустановить более 20 раз на моем локальном компьютере с приложением, которое получает эту ошибку при первом повторном развертывании, и все прошло прекрасно.

JRockit предназначен для интеграции в OpenJDK, поэтому, возможно, эта проблема исчезнет и для стандартной Java в будущем.

http://www.oracle.com/technetwork/middleware/jrockit/overview/index.html

И это бесплатно, под той же лицензией, что и HotSpot:

https://blogs.oracle.com/henrik/entry/jrockit_is_now_free_and

Для справки: есть новая версия инструмента Plumbr, которая также может отслеживать и обнаруживать утечки постоянного поколения.

Вы должны включить сборку мусора PermGen. По умолчанию Hotspot VM НЕ собирает мусор PermGen, что означает, что все загруженные файлы классов остаются в памяти навсегда. Каждое новое развертывание загружает новый набор файлов классов, что означает, что в конечном итоге вам не хватит места PermGen.

Какую версию Tomcat вы используете? Tomcat 7 и 6.0.30 имеют множество функций, позволяющих избежать этих утечек или, по крайней мере, предупредить вас об их причине.

Эта презентация Марка Томаса из SpringSource (и давнего коммиттера Tomcat) на эту тему очень интересна.

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