【问题标题】:java.lang.OutOfMemoryError: GC overhead limit exceeded Spring Hibernate Tomcat 6java.lang.OutOfMemoryError:GC 开销限制超出了 Spring Hibernate Tomcat 6
【发布时间】:2012-04-25 02:32:25
【问题描述】:

我在使用 Spring + Hibernate 的 Web 应用程序中遇到问题。

我随机出现错误

java.lang.OutOfMemoryError: 超出 GC 开销限制

当 web 应用在 tomcat 中运行时

我尝试获取堆转储并使用 Eclipse MAT 对堆转储进行了分析

这是我的发现

对象org.hibernate.impl.SessionFactoryObjectFactory持有86%的内存,这个对象的Fashhashmap实例持有超过100000个Hashmap。 在每个 Hashmap 中都有一个 org.hibernate.impl.SessionFactoryImpl 的实例, 似乎 org.hibernate.impl.SessionFactoryImpl 被加载了几次并存储在 org.hibernate.impl.SessionFactoryObjectFactory 的 Fashhashmap 中

有人可以帮我找到这个问题的根本原因并提出一些解决方案来解决这个问题。

【问题讨论】:

  • 你能告诉我们你是如何在 Spring 中配置 Hibernate 它的,你如何管理事务和一些示例 Hibernate 查询?可以匿名。

标签: spring hibernate out-of-memory


【解决方案1】:

好吧,即使你得到了SessionFactoryObjectFactory holds 86% of the memory,对我来说这似乎也不是原因。第一件事是在依赖任何内存分析工具之前,我们应该先了解这个工具如何预测出outofmemory问题。 内存工具只是尝试捕获运行该工具后在应用程序中显示的即时 HIKES。我很确定您会得到相同的错误日志,但由于工具提到的不同原因,Catalina web class loader 正在访问大量内存,这是显而易见的,也是意料之中的。

所以我只是想弄清楚,与其依赖任何此类工具(在特定情况/实现中可能正确),不如尝试挖掘您的应用程序源代码并尝试找到在何处创建了不必要的临时对象.

出于调试目的,您可以打开 JVM 选项 - -XX:-PrintGCDetails 以查看 GC 正在收集的具体内容。

有关更多信息,请参阅这些帖子/参考资料 - http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#Options java.lang.OutOfMemoryError: GC overhead limit exceeded

【讨论】:

    【解决方案2】:

    您的 GC 线程正在花费 98% 或更多的处理器时间来尝试清理对象。

    工厂模式的想法是返回您希望创建的对象的非空实例,这通常通过在实例化后返回相同的实例来完成。

    现在可能是您有 100,000 个不同的会话或诸如此类的东西,但我怀疑这是正确的,因此您需要检查您的代码以确保工厂方法调用正确关闭,并且可能没有缓存本地副本.

    如果您确实有 100,000 个会话,请仔细查看创建它们的方法。分解长方法,以便循环和 while 结构由方法调用分隔,以便方法局部变量一旦超出范围就可以清理。

    还要确保这些较小的方法不是最终的,因为编译器会将最终方法拼接到单个堆栈帧中作为一种优化技术。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      相关资源
      最近更新 更多