Java 大量表和休眠内存消耗

Java 大量表和休眠内存消耗,java,spring,hibernate,jpa,memory,Java,Spring,Hibernate,Jpa,Memory,我正在从事一个大型ERP项目,该项目的数据库模型大约有2100个表。使用Hibernate映射的“仅”500个表,部署在web服务器上的应用程序需要大约3GB的工作内存 在一个持久化单元中使用这么多表时,有没有办法减少Hibernate的元模型内存占用?或者我应该放弃使用ORMs,转而使用普通的老JDBC(甚至是其他) 现在我正在使用Hibernate 4.1.8、Spring 3.1.3、JBoss AS 7.1和MSSQL数据库 编辑: -使用2000个生成的测试表,这些测试表的范围比原始d

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

在一个持久化单元中使用这么多表时,有没有办法减少Hibernate的元模型内存占用?或者我应该放弃使用ORMs,转而使用普通的老JDBC(甚至是其他)

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

编辑:

-使用2000个生成的测试表,这些测试表的范围比原始db模型小一点(因此“仅”1.3GB的已用内存)

编辑2:

Java MAT堆分析:


我建议在生产或暂存中对应用程序进行分析,以找出在何处或谁消耗了最大内存,并根据分析结果决定应在应用程序中进行哪些更改


Java melody非常易于集成和配置,在生产环境中,只需更新web.xml即可启用或禁用。一个开放的hibernate会话在使用过程中往往会累积对象。这不是内存泄漏;hibernate会话被设计为对请求使用一次,它缓存持久的对象(即会话中的活动对象)以及查询和其他数据。如果调用
session.toString()
,您将看到会话中存在的对象的详细列表

如果使用大量的对象,请考虑批处理对象。您可以在每个批处理之后调用

session.clear()
,从会话中移出缓存数据和持久对象,并减少会话的内存占用(有时会大幅减少)

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

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

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

sessionFactory.getStatistics().setStatisticsEnabled(true);

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

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

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


你知道hibernate消耗了多少3GB内存吗?考虑到消耗了约10个表的内存不足256MB,我估计它的北端是2.74GB:)你想试试Batoo JPA吗。明天我们将尝试这样做,并用结果更新问题,感谢您的建议。添加了JavaMelody中的内存直方图。无法从直方图中看出多少,但您应该查找消耗最大内存的类,然后检查谁持有它们。不确定找出内存使用情况及其瓶颈是否容易。是的,问题在于我最初假设的情况。添加了MAT输出以供参考。从内存消耗来看,我认为大部分内存由会话工厂保留,您是否使用缓存?或者在持久性上下文中加载大量对象?项目需求是多个RDBMS目标(即Oracle、PGSQL、MSSQL、MySQL…),这让ibatis成为一个非常昂贵的选择。另外,我非常不同意Hibernate只适合CRUD操作。