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

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

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

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


当前回答

谁在IntelliJ中调试JBoss应用程序时遇到了同样的问题: 我刚刚在运行/调试配置的虚拟机选项中添加了-XX: MaxPermSize = 128m。你可以把它增加到256m,以确保它会工作。

其他回答

我尝试了几个答案,最终完成工作的唯一一件事是在pom中的编译器插件的配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <fork>true</fork>
        <meminitial>128m</meminitial>
        <maxmem>512m</maxmem>
        <source>1.6</source>
        <target>1.6</target>
        <!-- prevent PermGen space out of memory exception -->
        <!-- <argLine>-Xmx512m -XX:MaxPermSize=512m</argLine> -->
    </configuration>
</plugin>

希望这一点能有所帮助。

我有我们在这里谈论的问题,我的场景是eclipse-helios + tomcat + jsf,而您所做的是将一个简单的应用程序部署到tomcat。我在这里展示了同样的问题,解决方法如下。

在eclipse转到服务器选项卡双击注册服务器在我的情况下tomcat 7.0,它打开我的文件服务器一般注册信息。在“一般信息”部分单击“打开启动配置”链接,这将打开在虚拟机参数参数选项卡中添加的服务器选项的执行,最后添加这两个条目

-XX: MaxPermSize = 512m
-XX: PermSize = 512m

和准备好了。

我添加-XX: MaxPermSize = 128m(你可以实验哪个工作得最好)到虚拟机参数,因为我使用eclipse ide。在大多数JVM中,默认的PermSize大约是64MB,如果项目中有太多的类或大量的字符串,就会耗尽内存。

对于eclipse,在answer中也有描述。

步骤1:在Servers选项卡中双击tomcat服务器

步骤2:打开启动Conf,并在现有VM参数的末尾添加-XX: MaxPermSize = 128m。

人们常犯的错误是认为堆空间和永久空间是相同的,这是完全错误的。您可能在堆中有很多剩余空间,但仍然可能在permgen中耗尽内存。

Common causes of OutofMemory in PermGen is ClassLoader. Whenever a class is loaded into JVM, all its meta data, along with Classloader, is kept on PermGen area and they will be garbage collected when the Classloader which loaded them is ready for garbage collection. In Case Classloader has a memory leak than all classes loaded by it will remain in memory and cause permGen outofmemory once you repeat it a couple of times. The classical example is Java.lang.OutOfMemoryError:PermGen Space in Tomcat.

现在有两个方法来解决这个问题: 1. 检查内存泄漏的原因或是否存在内存泄漏。 2. 通过使用JVM参数-XX:MaxPermSize和-XX:PermSize来增加PermGen空间的大小。

你也可以在Java中查看Java.lang. outofmemoryerror的2 Solution来了解更多细节。

Jrockit也帮我解决了这个问题;但是,我注意到servlet的重启时间要短得多,所以虽然在生产环境中效果更好,但在开发过程中却有点拖后腿。