最近我在我的 Web 应用程序中遇到了这个错误:
java.lang.OutOfMemoryError:PermGen 空间
这是在 Tomcat 6 和 JDK 1.6 上运行的典型 Hibernate / JPA + IceFaces / JSF 应用程序。显然,重新部署应用程序几次后就会发生这种情况。
导致它的原因以及可以采取哪些措施来避免它?我该如何解决这个问题?
解决方案是在启动 Tomcat 时将这些标志添加到 JVM 命令行:
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
您可以通过关闭 tomcat 服务,然后进入 Tomcat / bin 目录并运行 tomcat6w.exe 来实现。在 “Java” 选项卡下,将参数添加到 “Java 选项” 框中。单击 “确定”,然后重新启动该服务。
如果您收到错误, 则指定的服务不作为已安装的服务存在,您应该运行:
tomcat6w //ES//servicename
其中servicename是 services.msc 中查看的服务器名称
资料来源:orx 对Eric 的 Agile Answers的评论。
你最好试试-XX:MaxPermSize=128M
而不是-XX:MaxPermGen=128M
。
我无法准确地使用这个内存池,但它与加载到 JVM 中的类的数量有关。 (因此为 tomcat 启用类卸载可以解决问题。)如果应用程序在运行时生成并编译类,则更可能需要大于默认值的内存池。
多个部署后发生的应用程序服务器 PermGen 错误很可能是由容器保存到旧应用程序的类加载器中的引用引起的。例如,使用自定义日志级别类将导致应用程序服务器的类加载器保留引用。您可以使用现代(JDK6 +)JVM 分析工具(如 jmap 和 jhat)来查看这些类间加载器泄漏,以查看应用程序中继续保留哪些类,以及重新设计或消除它们的使用。通常的嫌疑人是数据库,记录器和其他基础框架级库。
请参阅Classloader 泄漏:可怕的 “java.lang.OutOfMemoryError:PermGen space” 异常 ,特别是其后续帖子 。