12

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

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

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

编辑:

JavaMelody 内存直方图输出- 生成了 2000 个测试表,这些测试表的范围比原始 db 模型小一些(因此“仅”使用了 1.3GB 的内存)

编辑2:

Java MAT 堆分析:

4

4 回答 4

5

一个打开的休眠会话将倾向于在使用时累积对象。这不是内存泄漏;休眠会话被设计为一次请求使用,它缓存持久的对象(即在会话中活动),以及查询和其他数据。如果您调用session.toString(),您将看到会话中存在的对象的洗衣清单。

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

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

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

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

sessionFactory.getStatistics().setStatisticsEnabled(true);
于 2012-12-06T01:53:51.817 回答
4

我建议使用java melody对生产或登台应用程序进行分析,以找出消耗最大内存的位置或人员,并根据分析结果决定应在应用程序中进行哪些更改。

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

于 2012-11-26T14:54:25.067 回答
2

我遇到了同样的问题,我成功地将内存消耗从 xGB 减少到 30M,buildSessionFactory 从 2 分钟到 7 秒。

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

postInstantiate buildSessionFactory 慢/内存巨大的数据库

于 2015-06-04T08:55:34.877 回答
1

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

于 2012-12-06T05:24:33.933 回答