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

JBoss 7, java.lang.OutOfMemoryError: пространство PermGen

Я столкнулся с этой ошибкой, когда использование процессора переходит в его пределы, и JBoss нуждается в перезагрузке (java.lang.OutOfMemoryError: PermGen space).

Я нашел решение для более старой версии JBoss для увеличения MaxPermSize. Я думаю, что то же самое касается JBoss7.

Какое значение было бы достаточно хорошим, чтобы не столкнуться с какой-либо проблемой снова? Есть ли способ окончательно уйти от этой проблемы (например, скажем, использовать другую виртуальную машину, например JRockit)?

4b9b3361

Ответ 1

Так как это происходит после нескольких повторных развертываний, похоже, что вы столкнулись с утечкой classloader, обычным типом перекрестной утечки.

Эти прекрасные звери происходят из-за нормальных (не слабых) ссылок на объекты, принадлежащие контейнеру, на объекты, которые являются экземплярами классов, загружаемых из загрузчика класса приложения. Если эти ссылки не очищаются при undeploy, все еще существует сильная ссылочная цепочка к загрузчику классов приложений, поэтому он не может быть GC'd, и загруженные классы не могут быть освобождены.

Общей причиной являются статические коллекции в классах контейнеров, в которых добавлены нестатические ссылки на классы приложений.

JBoss AS 7 имеет довольно сильные положения в своей модульной системе, чтобы предотвратить утечку класса загрузчика, поэтому я удивлен, что вам удалось запустить его. Я не видел утечку загрузчика классов, так как я перешел в AS7 из Glassfish.

Увеличение MaxPermSize купит вам некоторое время, но оно не избавится от проблемы.

Вам действительно нужно разобраться, почему происходит утечка класса. Делать это "весело". Вам нравятся налоги, прерывистые ошибки и чистка душа, верно? См. Ссылки в первом параграфе для некоторых блогов, которые помогут вам начать отслеживание утечки. В принципе, вы захотите использовать VisualVM и OQL для поиска ссылок на ваше приложение classloader или взять кучу кучи и использовать jhat (часть JDK), чтобы найти ссылки. В любом случае, идея состоит в том, чтобы выяснить, где сильная цепочка ссылок с сервера приложений на ваш загрузчик классов через экземпляры ваших классов приложений.

В качестве альтернативы, он может помочь взять копию вашего приложения, а затем начать копирование битов из него, пока утечка не исчезнет. Вы можете сказать, протекает ли он путем подключения VisualVM или другого мониторинга к виртуальной машине сервера приложений и просмотра, чтобы увидеть, увеличивается ли PermGen после двух или более циклов развертывания/развертывания. Рассмотрим автоматизацию циклов развертывания/развертывания. Уточните причину утечки в малую часть вашего приложения и/или одну из его зависимостей и создайте небольшой автономный тестовый пример, затем отправьте это как отчет об ошибке на (a) JBoss AS 7, так как AFAIK it чтобы остановить это событие, и (б) виновник, который держит ссылку.

Если вы сократите причину до зависимости, входящей в состав вашего архива развертывания, перемещение его в модуль JBoss AS 7 может позаботиться о проблеме. Создайте для него модуль JBoss, разверните его в каталоге modules AS7 и добавьте зависимость от него к развертыванию через ваш Manifest.MF или через jboss-deployment-structure.xml. См. Документацию на загрузчике классов AS7.

Вот почему тот факт, что Project Jigsaw был отложен, меня огорчает. Java нуждается в сильной модульной системе, которая избавляется от этой crud.

Ответ 2

Параметр VM:

-XX:MaxPermSize=256M

Просто сделайте его достаточно большим, чтобы вы не достигли предела.

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

Ответ 3

Мы должны были сделать то же самое, и, к сожалению, visualvm не очень много для нас.

Мы закончили использование коврика eclipse для анализа дампа кучи, сгенерированного при сбое, а затем проверили отчет leak suspects, в котором говорилось, что было сделано несколько экземпляров ModuleClassLoader.

Нажав на один из экземпляров на вкладке "Обзор", а затем выбрав merge shortest paths to GC roots + exclude weak references, мы получили нашего виновника, который не позволял этим экземплярам ModuleClassLoader быть GC'ed!

https://smalldata.tech/blog/2015/09/29/detecting-java-permgen-memory-leak

Ответ 4

Почему это происходит?

Ошибка "PermGen" возникает, когда на виртуальной машине Java заканчивается память в постоянном поколении. Напомним, что Java имеет сборщик мусора поколения, с четырьмя поколениями: eden, young, старых и постоянных. В гене eden объекты очень короткие живая и мусорная коллекция быстрая и часто. Молодое поколение состоит из объектов, которые пережили поколение эдов (или были нажаты вплоть до молодых, потому что поколение эдов было заполнено во время распределение), сбор мусора в молодом поколении меньше часто, но все же происходит довольно регулярно (при условии, что ваше приложение действительно что-то делает и выделяет объекты каждый сейчас и потом). Старое поколение, ну, вы это поняли. Это содержит объекты, которые пережили молодое поколение или были отброшены, и сбор мусора еще менее редки, но все равно может произойти. И, наконец, постоянное поколение. Это для объектов, которые виртуальная машина решила поддержать вечную жизнь, которая в первую очередь суть проблемы. Объекты постоянного поколения никогда не собираются мусор; то есть при нормальных обстоятельствах, когда jvm запускается с обычными параметрами командной строки. И что происходит при повторном развертывании вашего веб-приложения, что ваш файл WAR распаковывается, а файлы классов загружаются в jvm. И здесь вещь: почти всегда попадает в постоянное поколение... (принято из: http://rlogiacco.blogspot.com/2009/02/jboss-and-permgen-outofmemoryerror.html)

Вот несколько советов:

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

set JAVA_OPTS=-Xms512m -Xmx1024m 
-XX:PermSize=512m 
-XX:MaxPermSize=1024m 
-XX:+UseConcMarkSweepGC 
-XX:+CMSPermGenSweepingEnabled 
-XX:+CMSClassUnloadingEnabled 
  • Параметр CMSPermGenSweepingEnabled включает PermGen в запуск мусора. По умолчанию пространство PermGen никогда не включенной в сбор мусора (и, таким образом, растет без границ).
  • Параметр CMSClassUnloadingEnabled сообщает мусору PermGen чтобы выполнить действия над объектами класса. По умолчанию класс объекты получают освобождение, даже когда пространство PermGen посетили во время сбора гаражей.

Перезапустите JBOSS, потому что каждый раз, когда вы развертываете приложение, вы увеличиваете объем данных в PermGen.

Вы также можете использовать JRocket JVM вместо Sun JVM. он не имеет PermGen в своем алгоритме Collector Garbage.