最近,我在我的web应用程序中遇到了这个错误:
java.lang.OutOfMemoryError:永久生成空间
它是一个典型的Hibernate/JPA + IceFaces/JSF应用程序,运行在Tomcat 6和JDK 1.6上。 显然,这可能发生在重新部署应用程序几次之后。
是什么原因导致的,如何避免呢? 我该如何解决这个问题?
最近,我在我的web应用程序中遇到了这个错误:
java.lang.OutOfMemoryError:永久生成空间
它是一个典型的Hibernate/JPA + IceFaces/JSF应用程序,运行在Tomcat 6和JDK 1.6上。 显然,这可能发生在重新部署应用程序几次之后。
是什么原因导致的,如何避免呢? 我该如何解决这个问题?
当前回答
outofmemoryerror: PermGen space消息表示内存中的永久生成区域已耗尽。
任何Java应用程序都允许使用有限的内存。特定应用程序可以使用的确切内存量是在应用程序启动时指定的。
Java内存被划分为不同的区域,如下图所示:
Metaspace:一个新的内存空间诞生
JDK 8 HotSpot JVM现在使用本机内存来表示类元数据,被称为Metaspace;类似于Oracle的JRockit和IBM的JVM。
好消息是,这意味着不再存在java.lang.OutOfMemoryError: PermGen空间问题,也不再需要使用Java_8_Download或更高版本来调优和监视这个内存空间。
其他回答
或者,你可以切换到JRockit,它处理permgen的方式不同于sun的jvm。它通常也有更好的性能。
http://www.oracle.com/technetwork/middleware/jrockit/overview/index.html
你最好尝试-XX:MaxPermSize=128M而不是-XX:MaxPermGen=128M。
我不能确切地说出这个内存池的使用情况,但它与装入JVM中的类的数量有关。(因此,为tomcat启用类卸载可以解决这个问题。)如果您的应用程序在运行时生成和编译类,则更可能需要比默认值更大的内存池。
你也可以通过以下方法来解决这个问题:
rm -rf <tomcat-dir>/work/* <tomcat-dir>/temp/*
清除工作目录和临时目录将使Tomcat重新启动。
解决方案是在启动Tomcat时将这些标志添加到JVM命令行:
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
您可以通过关闭tomcat服务,然后进入tomcat /bin目录并运行tomcat6w.exe来做到这一点。在“Java”选项卡下,将参数添加到“Java选项”框。单击“确定”,然后重新启动服务。
如果你得到一个错误,指定的服务不存在作为一个安装的服务,你应该运行:
tomcat6w //ES//servicename
其中servicename是在services.msc
来源:orx对Eric敏捷回答的评论。
App server PermGen errors that happen after multiple deployments are most likely caused by references held by the container into your old apps' classloaders. For example, using a custom log level class will cause references to be held by the app server's classloader. You can detect these inter-classloader leaks by using modern (JDK6+) JVM analysis tools such as jmap and jhat to look at which classes continue to be held in your app, and redesigning or eliminating their use. Usual suspects are databases, loggers, and other base-framework-level libraries.
参见类加载器泄漏:可怕的“java.lang。OutOfMemoryError: PermGen space”异常,特别是它的后续帖子。