最近,我在我的web应用程序中遇到了这个错误:

java.lang.OutOfMemoryError:永久生成空间

它是一个典型的Hibernate/JPA + IceFaces/JSF应用程序,运行在Tomcat 6和JDK 1.6上。 显然,这可能发生在重新部署应用程序几次之后。

是什么原因导致的,如何避免呢? 我该如何解决这个问题?


当前回答

我遇到了完全相同的问题,但不幸的是,建议的解决方案都不适合我。这个问题在部署过程中没有发生,我也没有进行任何热部署。

在我的例子中,这个问题每次都发生在我的web应用程序执行期间的同一时间点,同时(通过hibernate)连接到数据库。

这个链接(前面也提到过)提供了足够的内部组件来解决这个问题。将jdbc-(mysql)-driver从WEB-INF移到jre/lib/ext/文件夹中似乎已经解决了这个问题。这不是理想的解决方案,因为升级到更新的JRE需要重新安装驱动程序。 另一个可能导致类似问题的候选是log4j,因此您可能也想移动它

其他回答

由于使用了较大的空间而不是jvm提供的空间来执行代码,会发生Perm gen space错误。

在UNIX操作系统中,这个问题的最佳解决方案是更改bash文件上的一些配置。以下步骤可以解决该问题。

在终端上执行gedit .bashrc命令。

用以下值创建JAVA_OTPS变量:

export JAVA_OPTS="-XX:PermSize=256m -XX:MaxPermSize=512m"

保存bash文件。在终端上执行exec bash命令。重新启动服务器。

我希望这个方法能解决你的问题。如果您使用低于8的Java版本,有时会出现此问题。但是如果你使用Java 8,这个问题就不会发生。

outofmemoryerror: PermGen space消息表示内存中的永久生成区域已耗尽。

任何Java应用程序都允许使用有限的内存。特定应用程序可以使用的确切内存量是在应用程序启动时指定的。

Java内存被划分为不同的区域,如下图所示:

Metaspace:一个新的内存空间诞生

JDK 8 HotSpot JVM现在使用本机内存来表示类元数据,被称为Metaspace;类似于Oracle的JRockit和IBM的JVM。

好消息是,这意味着不再存在java.lang.OutOfMemoryError: PermGen空间问题,也不再需要使用Java_8_Download或更高版本来调优和监视这个内存空间。

你最好尝试-XX:MaxPermSize=128M而不是-XX:MaxPermGen=128M。

我不能确切地说出这个内存池的使用情况,但它与装入JVM中的类的数量有关。(因此,为tomcat启用类卸载可以解决这个问题。)如果您的应用程序在运行时生成和编译类,则更可能需要比默认值更大的内存池。

解决方案是在启动Tomcat时将这些标志添加到JVM命令行:

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

您可以通过关闭tomcat服务,然后进入tomcat /bin目录并运行tomcat6w.exe来做到这一点。在“Java”选项卡下,将参数添加到“Java选项”框。单击“确定”,然后重新启动服务。

如果你得到一个错误,指定的服务不存在作为一个安装的服务,你应该运行:

tomcat6w //ES//servicename

其中servicename是在services.msc

来源:orx对Eric敏捷回答的评论。

他们说Tomcat的最新版本(6.0.28或6.0.29)可以更好地处理重新部署servlet的任务。