JBoss Weld + java.lang.OutOfMemoryError: пространство PermGen

Я только что переключился на Weld, чтобы использовать CDI JSF 2 Beans + область разговора.

Здесь моя зависимость maven:

    <dependency>
        <groupId>org.jboss.weld.servlet</groupId>
        <artifactId>weld-servlet</artifactId>
        <version>1.0.1-Final</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

Здесь запись в моем web.xml:

<listener>
  <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>

Одна вещь, которую я сразу заметил, - это просто перезагрузить мой tomcat 7 примерно 2 раза, а java.lang.OutOfMemoryError: PermGen space появится в файле журнала catalina.out.

Прежде чем использовать Weld, я могу перезагрузить мой tomcat 7 для более чем 10 раз безопасно без java.lang.OutOfMemoryError. Я думал, что увеличение моего варианта Xmx в catalina.sh поможет, но это не помогло мне. JAVA_OPTS=-Xmx1024m

Это нормально?

Ответ 1

Это действительно очень типичная ошибка, когда вы хотите перейти на Java EE с помощью простого сервлетконтейнера, который не предназначен для этого;)

Нет, просто шучу. Tomcat поставляется с настройкой по умолчанию, установленной только 64 МБ. В частности, там хранятся определения Class (т.е. Все, что вы получаете, когда делаете Class#forName()). Грубо говоря, Weld сканирует каждый JAR и класс в classpath, чтобы найти аннотации, чтобы он мог программно создать сопоставление памяти конфигурации проводки (перед аннотациями это обычно достигалось с помощью XML файлов). Тем не менее, имея много классов в пути к классам и загружая много классов, вы покидаете очень мало места в пространстве перменто для hotdeploys Tomcat.

Есть несколько способов обойти это. Наиболее логичным способом было бы увеличить пространство пермгенов. Вы можете установить его как аргумент виртуальной машины. 256 МБ - хорошее начало.

-XX:MaxPermSize=256m

Если вы используете Tomcat из Eclipse, вам нужно установить его, дважды щелкнув запись сервера в представлении "Серверы", щелкнув ссылку "Открыть запуск конфигурации", нажав вкладку "Аргументы" и затем добавив ее (пробел) в поле "Аргументы VM".

Кроме того, вы также можете заставить JVM быть более экономно с пространством permgen. Объекты там по умолчанию редко выгружаются. Добавьте следующие аргументы VM.

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

См. также:

Ответ 2

Попробуйте установить permsize: -XX:MaxPermSize=200m. Вероятно, вы загружаете множество определений классов и, следовательно, заполняете пространство постоянного поколения.

Ответ 3

За исключением увеличения PermGen, вы также должны исключать пакеты, которые не являются сварными, из сканера Weld. См. Здесь:

20.1. Исключение классов из сканирования и развертывания

<?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://java.sun.com/xml/ns/javaee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns:weld="http://jboss.org/schema/weld/beans" 
         xsi:schemaLocation="
            http://java.sun.com/xml/ns/javaee http://docs.jboss.org/cdi/beans_1_0.xsd
            http://jboss.org/schema/weld/beans http://jboss.org/schema/weld/beans_1_1.xsd">

      <weld:scan>

          <!-- Don't deploy the classes for the swing app! -->
          <weld:exclude name="com.acme.swing.**" />

          <!-- Don't include GWT support if GWT is not installed -->
          <weld:exclude name="com.acme.gwt.**">
              <weld:if-class-available name="!com.google.GWT"/>
          </weld:exclude>

          <!--
              Exclude classes which end in Blether if the system property verbosity is set to low
              i.e.  java ... -Dverbosity=low            
          -->        
          <weld:exclude pattern="^(.*)Blether$">
              <weld:if-system-property name="verbosity" value="low"/>
          </weld:exclude>

         <!--
               Don't include JSF support if Wicket classes are present, and the viewlayer system
               property is not set
          -->
          <weld:exclude name="com.acme.jsf.**">
              <weld:if-class-available name="org.apahce.wicket.Wicket"/>
              <weld:if-system-property name="!viewlayer"/>
          </weld:exclude>
      </weld:scan>

  </beans>