Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Hibernate时内存使用率高_Java_Hibernate_Memory Leaks_Out Of Memory_Heap Dump - Fatal编程技术网

Java 使用Hibernate时内存使用率高

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命令转储

我用运行在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像这样。它可能无法通过垃圾收集进行处理,或者只能缓慢处理


如何修复它?

您的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哪个模块