【发布时间】:2016-04-08 19:14:29
【问题描述】:
我最近意识到一个应用程序消耗的内存超出了应有的水平。我做了一个JVM的线程转储,发现Hibernate SessionFactoryImpl中有数百兆的SQL查询。
这些查询在启动应用程序服务器时出现在内存中。我已经放弃了队列(JMS)或后台其他进程的假设。
查询有以下两种格式:
select
diferenc0_.id as id975_137_,
[...]
where diferenc0_.id=?
或者
select
diferenc0_.id as id975_137_,
[...]
where diferenc0_.id= IN (?,?,?,?,?,?,?,?) -- because default_batch_fetch_size = 8
我的 persistence.xml 配置(我关闭了 hbm2ddl):
"hibernate.hbm2ddl.auto", ""
"hibernate.query.startup_check", "false"
"hibernate.show_sql", "false"
"hibernate.format_sql", "false"
"hibernate.transaction.auto_close_session", "true"
"hibernate.cache.use_second_level_cache", "false"
"hibernate.cache.use_query_cache", "false"
"hibernate.jdbc.batch_size", "20"
"hibernate.default_batch_fetch_size", "8"
我使用的是 Hibernate 3.3.0。
另一个重要细节:这些查询不会发送到数据库!我与我们团队的 DBA 分析了 Jboss 启动时发送到数据库的查询。我们也不在系统中使用命名查询。
由于应用程序有点老,老开发人员在映射中使用了 fetch EAGER 资源。所以这些生成的查询真的很庞大。
问题:Hibernate 出于什么目的在应用程序启动时在内存中创建这些查询?
【问题讨论】:
-
Hibernate 以进行额外/无用查询(尤其是 EAGER 获取)而闻名,但至少它通过应用程序输入而不是自己启动它们。您确定您的应用程序不包含计时器、计划作业或在启动时和/或在固定时间后通过 Hibernate 启动查询的东西吗?
-
嗨!我确定。正如我所说,这个查询甚至没有发送到数据库。这看起来就像
hibernate.query.startup_check可以做的那样,但我已经将此选项设置为 false。 -
您能发布您的休眠/持久性配置文件吗?
-
@Baldurian,我用持久性文件和 Hibernate 版本(3.3.0,非常旧)更新了问题。