问题
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 ?
回答1:
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:
- Tomcat Wiki - OutOfMemory errors
回答2:
Try setting the permsize: -XX:MaxPermSize=200m
. You are probably loading lots of class definitions and therefore filling up the permanent generation space.
回答3:
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>
来源:https://stackoverflow.com/questions/5535408/jboss-weld-java-lang-outofmemoryerror-permgen-space