Java 如何使用';PermGen空间不足';Tomcat Spring Hibernate web应用程序中出现异常?

Java 如何使用';PermGen空间不足';Tomcat Spring Hibernate web应用程序中出现异常?,java,hibernate,spring,tomcat5.5,permgen,Java,Hibernate,Spring,Tomcat5.5,Permgen,我们有一个web应用程序,它使用SpringHibernate将注册用户数据持久化到Oracle数据库中。该应用程序在开发环境中运行良好,但当我们在具有更多数据的实时环境中复制它时,它失败了。最初,应用程序正常启动,但在执行一些操作后,出现“PermGen超出空间”异常 我已经开始在Google、Spring和Hibernate论坛上搜索,但是没有帮助。关于这个错误有很多讨论,但是对于每一个解决方案,都有人说:“它有效”,而其他人说“无效” 例如,许多人提出增加JVM参数-XX:MaxPermS

我们有一个web应用程序,它使用SpringHibernate将注册用户数据持久化到Oracle数据库中。该应用程序在开发环境中运行良好,但当我们在具有更多数据的实时环境中复制它时,它失败了。最初,应用程序正常启动,但在执行一些操作后,出现“PermGen超出空间”异常

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

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

我们使用Java1.5_0_09、Spring2.5和javaassist3.4.GA,Tomcat5.5作为web容器,Oracle10g作为数据库


谁能告诉我是什么导致了这个问题以及如何解决它吗?

这个
-XX:MaxPermSize
确实有效,你只需要得到正确的值。我相信,对于客户端模式的虚拟机,默认值是32mb,对于服务器模式的虚拟机,默认值是64mb。如果您有内存,我建议将其设置为256mb:

java -XX:MaxPermSize=256m

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

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

你看到了吗?它曾经帮助我解决了一个类似的问题。 总结一下链接:

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

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


我使用来调查这一点并发现问题。

您必须知道,Tomcat的某些版本在重新部署时存在内存泄漏。我在tomcat 6.0.x上遇到了这种情况

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

要发现漏洞,请使用JDK1.6和1.5附带的jconsole应用程序。您可以绑定到一个进程,并观察随着时间的推移内存的使用情况

您还可以阅读以下内容:


    • 现在是JDK 6的一部分的Visual GC提供了非常好的实时内存图形表示。你可以看到伊甸园、世代和永久空间的变化。你就是不明白为什么


      更新:在我的JDK1.6.0_13发行版中是bin/jvisualvm.exe。为它提供您要监视的进程的PID。

      此处的所有响应都与PermGen问题有关,该问题是由于多次重新启动web应用程序而发生的,但在这种情况下,问题已经在tomcat重新启动后的第一次部署中发生,因此,这不可能是ClassLoader的引用或commons日志记录的问题。

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


      另一种方法是使用探查器,我使用JProfiler,并用它查看应用程序。它将准确地告诉您问题的来源。

      我遇到了相同的问题,我认为Tomcat是这种情况的罪魁祸首

      然后我改为使用jetty,一切都很好,应用程序按预期部署/运行。
      因此,如果不一定要使用tomcat,那么我建议使用Jetty。

      并注意这只会延迟问题的解决。如果你的应用程序定期生成类,你就必须时不时地重新启动服务器。“看来我们几乎被它卡住了。”@skaffman,这是否意味着任何构建在Spring和Hibernate之上的应用程序都需要重新启动以防止PermGen上出现OOM?我希望我的服务器永远运行,除非推送新代码。@CK:很可能,是的。谷歌甚至不可能100%正常运行。如果你想获得99%以上的正常运行时间,你需要多台服务器。@skaffman,我也在同一个问题上苦苦挣扎。我一直在关注“永久”间距问题。但是我现在感觉很好,我知道原因了。谢谢你的信息,这很有趣。PermGen池以不透明著称,JVMTI调试接口看不到它。我想知道Vidual GC是如何在那里看到的?你在实习很多字符串吗?这不是一个答案,您应该编辑原始问题并添加此信息。