JBoss Weld + java.lang.OutOfMemoryError: PermGen space
Asked Answered
S

3

13

I've just switched to Weld to make use of CDI JSF 2 Beans + conversation scope.

Here's my maven dependency :

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

Here's the entry in my web.xml :

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

One thing i noticed immediately is i just need to reload my tomcat 7 for like 2 times, and the java.lang.OutOfMemoryError: PermGen space will show up in catalina.out log file.

Before using Weld, i can reload my tomcat 7 for like more than 10 times safely without the java.lang.OutOfMemoryError . I thought increasing my Xmx option in catalina.sh would help, but it didnt in my experience. JAVA_OPTS=-Xmx1024m

Is this normal ?

Sidky answered 4/4, 2011 at 6:52 Comment(3)
that's certainly not normal. but unless you do some digging in the code and find the part which consumes the memory, it's absolutely impossible to say if it's your code or the implementation itself...Frogman
@jan groth: i dont think it's my code, since it's a very simple testing project, like a jsf bean with a counter, etc. And before using weld, i was using spring or the default jsf managed bean, which were all fine.Sidky
JAVA_OPTS=-Xmx1024m does not increase Permgen. -XX:MaxPermSize=256m does.Chancery
B
5

This is indeed a very typical error when you want to go Java EE with a simple servletcontainer which isn't designed for that ;)

No, just kidding. Tomcat ships with a default permgen setting of only 64MB. Among others the Class definitions (i.e. whatever you get when you do Class#forName()) are stored there. Roughly put, Weld scans every single JAR and class in the classpath to find the annotations so that it can programmatically create a memory mapping of the wiring configuration (before annotations this was typically achieved by XML files). However, having many classes in the classpath and loading that much classes leaves very little room in permgen space for hotdeploys of Tomcat.

There are several ways to go around this. Most logical way would be to increase the permgen space. You can set it as a VM argument. 256MB is a good start.

-XX:MaxPermSize=256m

If you're using Tomcat from inside Eclipse, you need to set it by doubleclicking the server entry in Servers view, clicking Open launch configuration link, clicking Arguments tab and then adding it (space separated) to the VM Arguments field.

Further, you can also force JVM to be more sparingly with the permgen space. Objects in there are by default rarely unloaded. Add the following VM Arguments.

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

See also:

Burro answered 4/4, 2011 at 12:37 Comment(0)
E
1

Try setting the permsize: -XX:MaxPermSize=200m. You are probably loading lots of class definitions and therefore filling up the permanent generation space.

Economic answered 4/4, 2011 at 7:13 Comment(0)
R
1

Except for increasing PermGen, you should also exclude packages, which are not weld-aware, from Weld scanner. See here:

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>
Rochelle answered 8/5, 2011 at 8:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.