Подтвердить что ты не робот

Что можно сделать с исключением "PermGen out of space" в Tomcat- Spring -Hibernate веб-приложение?

У нас есть веб-приложение, которое использует Spring -Hibernate для сохранения данных зарегистрированных пользователей в базе данных Oracle. Приложение отлично работает в среде разработки, но когда мы копируем его в живую среду с гораздо большим количеством данных, она не удалась. Первоначально приложение запускается нормально, но после нескольких действий произошло исключение "PermGen out of space".

Я начал искать в форумах Google, Spring и Hibernate, но это не помогает. Существует много дискуссий об этой ошибке, но для каждого решения есть люди, которые говорят: "Это работает", а другие люди говорят: "Это не так".

Например, многие люди предлагают увеличить параметр -XX:MaxPermSize JVM, другие говорят, что он не работает. Есть сообщения, в которых говорится, что нужно использовать библиотеку javassist, а также другие библиотеки cglib. Другие говорят, что проблема в cglib.

Мы используем Java1.5_0_09, Spring 2.5 с javaassist3.4.GA, Tomcat 5.5 в качестве веб-контейнера и Oracle 10g в качестве базы данных.

Может кто-нибудь объяснить мне, что вызывает эту проблему и как ее решить?

4b9b3361

Ответ 1

-XX:MaxPermSize работает, вы должны получить правильное значение. По умолчанию, по-моему, 32 Мб для виртуальной машины с клиентом и 64 МБ для VM сервера. Я предлагаю установить его на 256 Мб, если у вас есть память:

java -XX:MaxPermSize=256m

Проблема возникает из-за того, что Spring и Hibernate могут сильно использовать классы, генерируемые во время выполнения, иногда их много. Эти сгенерированные классы все входят в пул памяти PermGen, поэтому, если вы используете эти рамки, вам часто нужно увеличить ваш PermGen до больших сумм.

Ответ 2

Вы должны знать, что некоторые версии Tomcat имеют утечки памяти при передислокации войны. Это случилось со мной на Tomcat 6.0.x.

Как и предполагалось, увеличьте MaxPermSize, это временное решение для вашей машины разработки - и когда вы получите ошибку, через 2-3 дня просто перезапустите сервер. На производстве не все так просто. Так что это работает для разработки, но этот подход не работает для производства, где у вас должны быть исправлены проблемы утечек памяти.

Чтобы обнаружить утечки, используйте приложение jconsole, которое поставляется с jdk 1.6 и 1.5. Вы можете привязаться к процессу и наблюдать за используемой памятью с течением времени.

Вы также можете прочитать это:

Ответ 3

Я видел эту проблему с Hibernate (используется без Spring). Проблема заключалась в том, что мы создавали экземпляр SessionFactory для каждого пользовательского запроса, а не создавали один экземпляр для времени жизни приложение.

Я использовал профилировщик YourKit, чтобы исследовать это и обнаружить проблему.

Ответ 4

Как скаффман говорит, что свойство -XX: MaxPermSize действительно работает, однако иногда у вас может быть основная проблема, которая может ограничивать только ограничение.

Вы видели эту заметку? Это помогло мне решить подобную проблему. Подводя итог ссылке:

  • Положите JDBC-драйвер в общий /lib (как документация tomcat), а не в WEB-INF/lib
  • Не помещайте commons-logging в WEB-INF/lib, поскольку tomcat уже загружает его

Ответ 5

Visual GC, теперь входящая в JDK 6, дает очень приятное графическое представление памяти в реальном времени. Вы можете видеть, что происходит с eden, поколением и perm пространствами. Вы просто не поймете, почему.

UPDATE: bin/jvisualvm.exe в моем дистрибутиве JDK 1.6.0_13. Дайте ему PID процесса, который вы хотите контролировать.

Ответ 6

Все ответы здесь относятся к проблеме PermGen, которая возникает из-за нескольких перезапусков веб-приложения, но в этом случае проблема уже возникает при первом развертывании после перезапуска tomcat, поэтому это не может быть проблемой ссылок ClassLoader или commons- каротаж.

Ответ 7

Если вы работаете на jdk6, вы можете использовать приложение jconsole для мониторинга использования памяти приложения и дальнейшего изучения.

Другой способ преследовать - использовать профилировщик, использовать JProfiler и взглянуть на приложение с этим. Он точно скажет вам, откуда эта проблема.

Ответ 8

Я столкнулся с той же проблемой, и я читал, что Tomcat является виновником этой ситуации.

Затем я переключился на пристань, и все получилось великолепно, и приложение развертывает/работает как ожидалось. Поэтому, если tomcat не является обязательным, я бы предложил Jetty.