Tomcat-Spring-Hibernate Web应用程序中的“PermGen out of space”exception可以做些什么?

我们有一个Web应用程序,它使用Spring-Hibernate将注册用户数据保存在Oracle数据库中。 该应用程序在开发环境中运行良好,但是当我们在具有更多数据的实时环境中复制它时,它失败了。 最初应用程序正常启动,但在几次操作之后发生’PermGen out of space’exception。

我已经开始在Google,Spring和Hibernate论坛上搜索,但它没有帮助。 关于这个错误有很多讨论,但对于每个解决方案,都有人说:“它有效”,而其他人说’它没有’。

例如,许多人提出增加-XX:MaxPermSize JVM参数,其他人说它不起作用。 有post说需要使用javassist库和其他库以及cglib库的问题。 其他人说问题出在cglib上。

我们使用Java1.5_0_09,Spring 2.5和javaassist3.4.GA,Tomcat 5.5作为web容器,Oracle 10g作为数据库。

任何人都可以解释一下导致这个问题的原因以及如何解决这个问题?

-XX:MaxPermSize确实有效,你必须得到正确的价值。 我相信默认情况下,客户端模式VM为32mb,服务器模式VM为64mb。 如果你有记忆,我建议把它设置为256mb:

 java -XX:MaxPermSize=256m 

出现这个问题是因为Spring和Hibernate可以大量使用运行时生成的类,有时候会占用很多。 这些生成的类都进入PermGen内存池,因此如果使用这些框架,通常需要将PermGen提升到大量。

您必须意识到某些版本的Tomcat在战争重新部署时存在内存泄漏。 它发生在tomcat 6.0.x上。

如建议增加MaxPermSize ,这是您的开发机器的临时解决方案 – 当您收到错误时,2-3天后,只需重新启动服务器。 生产并不那么简单。 所以这适用于开发 ,但这种方法不适用于生产 ,你应该修复内存泄漏问题。

要发现泄漏,请使用jdk 1.6和1.5附带的jconsole应用程序。 您可以绑定到进程,并观察一段时间内使用的内存。

你也可以阅读这些:

我已经看到了Hibernate的这个问题(没有Spring使用)。 问题在于我们为每个用户请求创建了一个SessionFactory实例,而不是为应用程序的生命周期创建单个实例。

我使用YourKit分析器来调查此问题并发现问题。

正如skaffman所说-XX:MaxPermSize属性确实有效,但有时你可能会遇到一个潜在的问题,即提高限制可能只会推迟。

你看过这张纸条吗? 它帮我解决了一次类似的问题。 总结链接:

  • 将JDBC驱动程序放在common / lib中(如tomcat文档所述 )而不是WEB-INF / lib
  • 不要将commons-logging放入WEB-INF / lib,因为tomcat已经引导它了

Visual GC现在是JDK 6的一部分,它实时提供了非常好的内存图形表示。 你可以看到伊甸园,世代和烫发空间发生了什么。 你只是不明白为什么。

更新:这是我的JDK 1.6.0_13发行版中的bin / jvisualvm.exe。 为它提供要监视的进程的PID。

这里的所有响应都与由于web-app的多次重启而发生的PermGen问题有关,但是在这种情况下,问题已经在tomcat重新启动后的第一次部署时发生,因此它不能成为ClassLoader的引用或公共日志记录的问题。

如果您在jdk6上运行,那么您可以使用jconsole应用程序来监视应用程序的内存使用情况并进一步调查。

另一个追求的途径是使用分析器,我使用JProfiler,并用它来看看应用程序。 它会告诉您问题的确切来源。

我遇到了同样的问题,我读过 Tomcat是这种情况的罪魁祸首。

然后我切换到docker,一切都变得很棒,应用程序按预期部署/运行。 因此,如果tomcat不是必须的,那么我建议Jetty。