JBoss Weld + java.lang.OutOfMemoryError:PermGen空间

时间:2011-04-04 06:52:15

标签: java jsf jsf-2 cdi jboss-weld

我刚刚切换到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之前,我可以在没有java.lang.OutOfMemoryError的情况下安全地重新加载我的tomcat 7超过10次。我认为在catalina.sh中增加我的Xmx选项会有所帮助,但这并不符合我的经验。 JAVA_OPTS=-Xmx1024m

这是正常的吗?

3 个答案:

答案 0 :(得分:5)

当您想要使用一个不是为此设计的简单servlet容器来使用Java EE时,这确实是一个非常典型的错误;)

不,只是在开玩笑。 Tomcat的默认permgen设置仅为64MB。其中Class定义(即你执行Class#forName()时得到的任何内容)都存储在那里。粗略地说,Weld在类路径中扫描每个单个JAR和类以查找注释,以便它可以以编程方式创建布线配置的内存映射(在通常由XML文件实现的注释之前)。但是,在类路径中有许多类并加载那么多类,在permgen空间中留下很少的空间用于Tomcat的热部署。

有几种方法可以解决这个问题。最合乎逻辑的方法是增加permgen空间。您可以将其设置为VM参数。 256MB是一个好的开始。

-XX:MaxPermSize=256m

如果您在Eclipse中使用Tomcat,则需要通过在 Servers 视图中双击服务器条目来设置它,单击打开启动配置链接,单击 Arguments 选项卡,然后将其(空格分隔)添加到 VM Arguments 字段。

此外,您还可以强制JVM更加谨慎地使用permgen空间。默认情况下很少卸载其中的对象。添加以下VM参数。

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

另见:

答案 1 :(得分:1)

尝试设置permsize:-XX:MaxPermSize=200m。您可能正在加载许多类定义,因此填补了永久生成空间。

答案 2 :(得分:1)

除了增加PermGen之外,您还应该从Weld扫描仪中排除不能识别焊接的包。见这里:

20.1. Excluding classes from scanning and deployment

<?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>