最近,我在我的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上。 显然,这可能发生在重新部署应用程序几次之后。
是什么原因导致的,如何避免呢? 我该如何解决这个问题?
当前回答
内存的配置取决于应用程序的性质。
你在做什么?
处理的交易数量是多少?
加载了多少数据?
etc.
etc.
etc
也许你可以配置你的应用程序,并开始清理一些模块从你的应用程序。
显然,这可能发生在重新部署应用程序几次之后
Tomcat采用热部署,但占用内存。试着每隔一段时间重新启动容器。此外,您还需要知道在生产模式下运行所需的内存量,这似乎是进行研究的好时机。
其他回答
你也可以通过以下方法来解决这个问题:
rm -rf <tomcat-dir>/work/* <tomcat-dir>/temp/*
清除工作目录和临时目录将使Tomcat重新启动。
对于Sun JVM,使用命令行参数-XX:MaxPermSize=128m(显然是将128替换为您需要的任何大小)。
从Tomcat的bin目录打开tomcat7w,或者在开始菜单中键入Monitor Tomcat (打开一个带有各种服务信息的选项卡窗口)。 在Java Options文本区域中添加这一行: - xx: MaxPermSize = 128 “初始内存池”设置为“1024”(可选)。 “最大内存池”设置为“1024”(可选)。 单击Ok。 重启Tomcat服务。
你最好尝试-XX:MaxPermSize=128M而不是-XX:MaxPermGen=128M。
我不能确切地说出这个内存池的使用情况,但它与装入JVM中的类的数量有关。(因此,为tomcat启用类卸载可以解决这个问题。)如果您的应用程序在运行时生成和编译类,则更可能需要比默认值更大的内存池。
First step in such case is to check whether the GC is allowed to unload classes from PermGen. The standard JVM is rather conservative in this regard – classes are born to live forever. So once loaded, classes stay in memory even if no code is using them anymore. This can become a problem when the application creates lots of classes dynamically and the generated classes are not needed for longer periods. In such a case, allowing the JVM to unload class definitions can be helpful. This can be achieved by adding just one configuration parameter to your startup scripts:
-XX:+CMSClassUnloadingEnabled
默认情况下,它被设置为false,因此要启用它,您需要显式地在Java选项中设置以下选项。如果你启用了CMSClassUnloadingEnabled, GC也会扫描PermGen并删除不再使用的类。请记住,此选项仅在UseConcMarkSweepGC也使用下面的选项启用时才有效。因此,当运行ParallelGC或串行GC时,请确保您已经通过指定将GC设置为CMS:
-XX:+UseConcMarkSweepGC