使用 Hibernate 时内存使用率高

Posted

技术标签:

【中文标题】使用 Hibernate 时内存使用率高【英文标题】:High memory usage when using Hibernate 【发布时间】:2014-08-13 02:09:17 【问题描述】:

我编写了一个在 linux 服务器上运行 java 的服务器端应用程序。 我使用休眠打开数据库会话,使用本机 sql 查询它,并始终通过 try、catch、finally 关闭此会话。

我的服务器以非常高的频率使用休眠查询数据库。

我已经将 MaxHeapSize 定义为 3000M,但它通常在 RAM 上使用 2.7GB,它可以减少但比增加慢。有时它会增长到 3.6GB 的内存使用量,超过我在启动时定义的 MaxHeapSize。

当使用的内存为 3.6GB 时,我尝试使用 -jmap 命令转储它并得到一个大小仅为 1.3GB 的 heapdump。

我用eclipse MAT分析一下,这里是MAT的支配树 我认为休眠是问题所在,我有很多这样的 org.apache.commons.collections.map.AbstractReferenceMap$ReferenceEntry。它可能无法通过垃圾回收处理,或者可以但很慢。

我该如何解决?

【问题讨论】:

【参考方案1】:

您的 IN 查询列表中有 250k 个条目。即使是本机查询也会使数据库瘫痪。出于性能原因,Oracle 将 IN 查询列表限制为 1000,因此您应该这样做。

给它更多的 RAM 并不能解决问题,您需要通过使用分页将您的选择/更新限制为最多 1000 个条目的批次。

Streaming 也是一个选项,但对于如此大的结果集,keyset pagination 通常是最佳选项。

如果您可以在数据库中完成所有处理,那么您就不必将 250k 记录从数据库移动到应用程序。许多 RDBMS 提供高级过程语言(例如 PL/SQL、T-SQL)是有充分理由的。

【讨论】:

你能再教我一点吗?我对oracle数据库交互的经验很少。 您需要获取 N 个条目,更新它们然后获取下一批,依此类推。 我仍然很困惑,在我的查询“UPDATE .. WHERE .. IN (...)”中,IN 查询列表很小,无法达到 1000。当我扩展到叶子时eclipse MAT中的支配树,我找到了我的选择查询(我的代码中的'sqlQueryCheckSet'),很多,我认为只有它 查看Hibernate issue。将“hibernate.query.plan_cache_max_soft_references”和“hibernate.query.plan_cache_max_strong_references”设置为一些适当的值。 太棒了。那么问题就得到了解答。【参考方案2】:

感谢Vlad Mihalcea 提供指向Hibernate issue 的链接,这是休眠中的错误,已在 3.6 版中修复。我只是将我的休眠版本 3.3.2 更新到版本 3.6.10,使用“hibernate.query.plan_cache_max_soft_references”(2048)、“hibernate.query.plan_cache_max_strong_references”(128)的默认值,我的问题就消失了。不再有高内存使用。

【讨论】:

我面临着类似的性能问题,您将哪个模块升级到 3.6.10【参考方案3】:

请注意,尽管可以配置和限制 queryPlanCache 中的对象数量,但拥有那么多可能并不正常。

在我们的例子中,我们在 hql 中编写类似于这样的查询:

hql = String.format("from Entity where msisdn='%s'", msisdn);

这导致 N 个不同的查询进入 queryPlanCache。当我们将此查询更改为:

hql = "from Blacklist where msisnd = :msisdn";
...
query.setParameter("msisdn", msisdn);

queryPlanCache 的大小从 100Mb 显着减少到几乎为 0。第二个查询被转换为一个单一的preparedStament,导致缓存中只有一个对象。

【讨论】:

以上是关于使用 Hibernate 时内存使用率高的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat 的 Catalina 实用程序线程定期使用高 CPU 和内存

当我滚动 Flatlist 时,内存使用率越来越高,当我停止滚动时内存没有释放(React Native)

使用纹理图集时 SpriteKit 中的高内存使用率

在 PyCharm 中分析 python 时内存使用率非常高

jpa hibernate中扫描太多实体时,glassfish启动很慢或内存泄漏

HSQL 和 Hibernate - 许多删除语句上的内存不足错误