PermGen空间异常

4

我正在使用JAVA 5 (32位)来运行我的应用程序,它在JBoss上运行良好。但是只有在32位系统上才能正常工作。当我们将其部署在64位的java5上时,它会抛出异常。

"java.lang.OutOfMemoryError: PermGen space" exception

是否需要补丁?

是否需要更改代码?

提前感谢。


你有没有查过google.com/search?q="java.lang.OutOfMemoryError%3A PermGen space"?有很多结果,包括在stackoverflow上的。 - Miserable Variable
@Hermal:它们不是一样的:这一个是关于PermGen空间,而另一个是关于堆空间。 - Joachim Sauer
(请注意,我链接的问题没有提到JBoss,但问题是相同的,答案比其他关于PermGen的问题更好。) - Joachim Sauer
@Joachim... 哎呀,我肯定是复制了PermGen问题。我会更改它。 - Miserable Variable
4个回答

7
当我在Tomcat或Jetty下运行我的Web应用程序时,遇到了同样的问题。永久代内存用于加载类,其思想是“类只加载一次,永远存在”。由于我使用了大量库和Spring框架,因此当我多次重新部署Web应用程序而没有重新启动Servlet容器时,这个内存很快就会被填满。
我发现仅仅增加最大永久代大小是不够的。您还需要允许垃圾回收在运行时删除未使用的类,否则将会被填满并抛出PermGen空间异常。以下是我为Servlet容器添加的JVM选项。
-XX:PermSize=128m -XX:MaxPermSize=256m -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled

-XX:MaxPermSize用于设置永久代的最大值。这个值应该大于默认值。

-XX:+CMSClassUnloadingEnabled选项允许JVM在运行时卸载类。默认情况下,禁用了类卸载。对于Java 5,请参阅此处

-XX:+UseConcMarkSweepGC,为了使类卸载选项起作用,必须设置此选项(ref)

此外,您应该考虑升级JVM版本。Java 5太旧了。


3

64位Java的指针长度是32位的两倍。由于大多数对象都由指针(对其他对象的引用)组成,因此需要更多的内存来运行。如果您的应用程序需要分配超过4GB的内存,那么您需要运行64位版本,不是吗?如果不需要,最好使用32位JVM。

在启动服务器时,请尝试使用-XX:MaxPermSize=参数。


2
Java 5.0 中的 64 位引用使用两倍长的引用。在 Java 6 中,默认情况下使用 32 位引用(请参见 -XX:+UseCompressedOops)。 - Peter Lawrey

2

是否需要补丁?

是的,使用默认使用32位引用的64位Java 6或7。 Java 5.0使用64位引用。 我不认为这将添加到Java 5.0中,因为它已经没有免费支持了近两年(顺便说一句,您可以付费获得支持)。

在Sun / Oracle JVM中,对象对齐为8字节。 JVM利用此事实使用32位引用来寻址32 GB的内存。 (8 * 4G)。 使用直接和内存映射内存,可以使用超过32 GB的内存。


0
创建一个环境变量,参数/值如下:
varible name = JAVA_OPTS

variable value = -Xmx1000M -XX:MaxPermSize=512m

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接