java - 大量表和 Hibernate 内存消耗

标签 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 堆分析:

最佳答案

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

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

在调用 session.clear() 之后,请注意在此调用之前加载的对象将恢复到 detached 状态,并且对于当前 session 不再处于 Activity 状态。

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

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

sessionFactory.getStatistics().setStatisticsEnabled(true);

关于java - 大量表和 Hibernate 内存消耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13567217/

相关文章:

Java 如何从用户计算机发送电子邮件/短信

java - Spring ScheduledTasks 未触发

java - Spring 事务管理器(注释样式)运行时错误

java - 自定义存储库基类 + QueryDslPredicateExecutor

java - 在 for 循环中使用 Hibernate save 方法将对象持久保存在数据库中的方法

java - 如果方法是事务性的,则 Spring 无法实例化 bean

java - Spring Roo - 未找到命令 'service'

java - Spring 将 servlet contextConfigLocation 类视为路径,尽管 contextClass 正确

hibernate - 在 Hibernate 中指定限制 "unique together"

java - 如果 C3P0 无法获得数据库连接,Tomcat 将挂起