大量的表和Hibernate内存消耗

时间:2012-11-26 14:47:49

标签: java spring hibernate jpa memory

我正在开发一个大型ERP项目,该项目拥有大约2100个表的数据库模型。仅使用""使用Hibernate映射的500个表,部署在Web服务器上的应用程序需要大约3GB的工作内存。

在一个持久性单元中使用那么多表时,有没有办法减少Hibernate的元模型内存占用?或者我应该放弃ORM并使用普通的旧JDBC(甚至是jOOQ)?

现在我正在使用Hibernate 4.1.8,Spring 3.1.3,JBoss AS 7.1并使用MSSQL数据库。

编辑:

JavaMelody memory histogram output - 使用2000个生成的测试表,这些测试表的范围比原始数据库模型小一点(因此仅消耗了1.3GB的内存)

编辑2:

Java MAT堆分析:

4 个答案:

答案 0 :(得分:5)

打开的hibernate会话会在使用时产生对象。这不是内存泄漏; hibernate会话被设计为对请求使用一次,并且它缓存持久(即在会话中生活)的对象,以及查询和其他数据。如果您致电session.toString(),您将看到会话中存在的对象清单。

如果使用大量对象,请考虑批量处理对象。您可以在每个批处理之后调用session.clear()以从会话中逐出缓存数据和持久对象,并减少会话的内存占用(有时会非常显着)。

调用session.clear()后,请注意在此调用之前加载的对象将恢复为分离的状态,并且不再对当前会话有效。

您还可以使用延迟提取来优化hibernate必须加载的数据量,以便处理给定的操作。您可以在hibernate文档中阅读更多相关信息。我建议启用hibernate的SQL日志记录功能,并检查hibernate是否正在撤回它不需要的数据。

您还可以配置hibernate以收集可以帮助您的统计信息:

sessionFactory.getStatistics().setStatisticsEnabled(true);

答案 1 :(得分:4)

我建议使用java melody分析生产中的应用程序或使用{{3}}进行分段,以找出消耗最大内存的位置或者谁,并根据分析结果,您应该决定应用程序应该进行哪些更改。

Java melody非常易于集成和配置,在生产中,您只需更新web.xml即可启用或禁用

答案 2 :(得分:2)

我重写了同样的问题,并且我成功地将内存消耗从xGB减少到30M,buildSessionFactory从2分钟传递到7个secondes。

解决方案的一个重要部分发布在这里

postInstantiate buildSessionFactory slow/memory huge database

答案 3 :(得分:1)

你的hibernate对象的目的是什么,hibernate只适用于CURD(创建,更新,读取,删除),但不适合计算。对于任何计算目的(特别是交叉表),使用存储过程和ibatis一起更好。