JBoss Weld + java.lang.OutOfMemoryError:PermGen空间
我刚刚切换到Weld来使用CDI JSF 2 Beans +会话范围。
这是我的maven依赖:
org.jboss.weld.servlet weld-servlet 1.0.1-Final jar compile
这是我的web.xml中的条目:
org.jboss.weld.environment.servlet.Listener
我立刻注意到的一件事是我只需要重新加载我的tomcat 7 2次,而java.lang.OutOfMemoryError: PermGen space
将显示在catalina.out日志文件中。
在使用Weld之前,我可以在没有java.lang.OutOfMemoryError的情况下安全地重新加载我的tomcat 7超过10次。 我认为在catalina.sh中增加我的Xmx选项会有所帮助,但这并不符合我的经验。 JAVA_OPTS=-Xmx1024m
这是正常的吗?
当您想要使用一个不是为此设计的简单servlet容器来使用Java EE时,这确实是一个非常典型的错误;)
不仅仅在开玩笑。 Tomcat的默认permgen设置仅为64MB。 其中, Class
定义(即你在执行Class#forName()
时获得的任何内容)都存储在那里。 粗略地说,Weld扫描类路径中的每个 JAR和类以查找注释,以便它可以以编程方式创建布线配置的内存映射(在注释之前,这通常由XML文件实现)。 但是,在类路径中有许多类并加载那么多类,在permgen空间中留下了很少的空间用于Tomcat的热部署。
有几种方法可以解决这个问题。 最合乎逻辑的方法是增加permgen空间。 您可以将其设置为VM参数。 256MB是一个好的开始。
-XX:MaxPermSize=256m
如果您在Eclipse中使用Tomcat,则需要通过双击Servers视图中的服务器条目,单击Open launch configuration链接,单击Arguments选项卡,然后将其添加(空格分隔)到VM Arguments字段来设置它。
此外,您还可以强制JVM更加谨慎地使用permgen空间。 默认情况下很少卸载其中的对象。 添加以下VM参数。
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
也可以看看:
- Tomcat Wiki – OutOfMemory错误
尝试设置permsize: -XX:MaxPermSize=200m
。 您可能正在加载许多类定义,因此填补了永久生成空间。
除了增加PermGen之外,您还应该从Weld扫描仪中排除不是焊接感知的包。 看这里:
20.1。 从扫描和部署中排除类