Java 使用Hibernate时内存使用率高
我用运行在linux服务器上的java编写了一个服务器端应用程序。 我使用hibernate打开到数据库的会话,使用本机sql进行查询,并始终通过try、catch和finally关闭此会话 我的服务器使用hibernate频繁地查询数据库 我已经定义了MaxHeapSize,因为它是3000M,但它通常在RAM上使用2.7GB,它可以减少,但比增加慢。有时它会增长到3.6GB的内存使用率,比我的MaxHeapSize定义的启动时间还要多 当使用的内存为3.6GB时,我尝试使用-jmap命令转储它,得到的heapdump大小仅为1.3GB 我使用EclipseMat来分析它,这里是来自MAT的支配树 我认为hibernate是个问题,我有这么多org.apache.commons.collections.map.AbstractReferenceMap$ReferenceEntry像这样。它可能无法通过垃圾收集进行处理,或者只能缓慢处理Java 使用Hibernate时内存使用率高,java,hibernate,memory-leaks,out-of-memory,heap-dump,Java,Hibernate,Memory Leaks,Out Of Memory,Heap Dump,我用运行在linux服务器上的java编写了一个服务器端应用程序。 我使用hibernate打开到数据库的会话,使用本机sql进行查询,并始终通过try、catch和finally关闭此会话 我的服务器使用hibernate频繁地查询数据库 我已经定义了MaxHeapSize,因为它是3000M,但它通常在RAM上使用2.7GB,它可以减少,但比增加慢。有时它会增长到3.6GB的内存使用率,比我的MaxHeapSize定义的启动时间还要多 当使用的内存为3.6GB时,我尝试使用-jmap命令转储
如何修复它?您的in查询列表中有250k个条目。即使是本机查询也会使数据库崩溃。出于性能原因,Oracle将IN查询列表限制为1000,因此您也应该这样做 给它更多的RAM并不能解决这个问题,您需要通过分页将您的选择/更新限制为最多1000个条目的批次 也是一个选项,但对于如此大的结果集,它通常是最佳选项
如果您可以在数据库中完成所有处理,那么您就不必将250k条记录从数据库移动到应用程序。许多RDBMS提供高级过程语言(例如PL/SQL、T-SQL)有一个很好的理由。谢谢
Vlad Mihalcea
和您的链接,这是hibernate上的bug,它在3.6版上修复。我只是将我的hibernate版本3.3.2更新到版本3.6.10,使用默认值“hibernate.query.plan\u cache\u max\u soft\u references”(2048)、“hibernate.query.plan\u cache\u max\u strong\u references”(128),我的问题就解决了。不再有高内存使用率。请注意,尽管queryPlanCache中的对象数量可以配置和限制,但拥有这么多可能并不正常
在我们的例子中,我们在hql中编写的查询与此类似:
hql = String.format("from Entity where msisdn='%s'", msisdn);
这导致N个不同的查询进入QueryLancache。当我们将此查询更改为:
hql = "from Blacklist where msisnd = :msisdn";
...
query.setParameter("msisdn", msisdn);
queryPlanCache的大小从100Mb急剧减小到几乎为0。第二个查询被转换为一个PreparedStatement,只在缓存中生成一个对象。你能教我多一点吗?我对oracle数据库交互几乎没有经验。您需要获取N个条目,更新它们,然后获取下一批等等。我仍然感到困惑,在我的查询“update..WHERE..in(…)”中,in查询列表很小,不能达到1000。当我在EclipseMat中展开到支配树的叶子时,我发现了我的select查询(代码中的“sqlQueryCheckSet”),其中有很多,我认为只有这一点。将“hibernate.query.plan\u cache\u max\u soft\u references”和“hibernate.query.plan\u cache\u max\u strong\u references”设置为一些适当的值。太好了。那么问题就解决了。我面临着类似的性能问题,你到底升级到了3.6.10哪个模块