使用Hibernate时内存使用率很高
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Hibernate时内存使用率很高相关的知识,希望对你有一定的参考价值。
我在linux服务器上用java运行代码服务器端应用程序。我使用hibernate打开数据库会话,使用本机sql查询它,并始终通过try,catch,finally关闭此会话。
我的服务器使用非常高频率的休眠查询数据库。
我已经定义了MaxHeapSize,因为它是3000M,但它通常在RAM上使用2.7GB,它可以减少但比增加慢。有时它的内存使用量会增长到3.6GB,比我的MaxHeapSize在启动时定义的要多。
当使用的内存为3.6GB时,我尝试使用-jmap命令转储它,并获得一个大小仅为1.3GB的heapdump。
我使用eclipse MAT来分析它,这里是来自MAT的统治者树我认为hibernate是问题,我有这么多org.apache.commons.collections.map.AbstractReferenceMap $ ReferenceEntry这样。它可能无法通过垃圾收集进行处理,或者可能会变慢。
我该如何解决?
您的IN查询列表中有250k个条目。即使是原生查询也会使数据库陷入困境。出于性能原因,Oracle将IN查询列表限制为1000,因此您应该这样做。
提供更多RAM并不能解决问题,您需要通过使用分页将选择/更新限制为最多1000个条目的批次。
Streaming is an option也是如此,但是,对于如此大的结果集,keyset pagination通常是最好的选择。
如果您可以在数据库中执行所有处理,那么您不必将250k记录从数据库移动到应用程序。许多RDBMS提供高级过程语言(例如PL / SQL,T-SQL)是有充分理由的。
请注意,即使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.第二个查询被转换为一个prepareStament,只在缓存中产生一个对象。
谢谢你Vlad Mihalcea
链接到Hibernate issue,这是hibernate的bug,它修复了3.6版本。我只是将我的hibernate版本3.3.2更新到版本3.6.10,使用默认值“hibernate.query.plan_cache_max_soft_references”(2048),“hibernate.query.plan_cache_max_strong_references”(128),我的问题就消失了。没有更高的内存使用率。
以上是关于使用Hibernate时内存使用率很高的主要内容,如果未能解决你的问题,请参考以下文章