垃圾收集开销限制 - 休眠

时间:2017-12-23 12:04:33

标签: java hibernate memory garbage-collection

我正在使用Hibernate查询我的MySQL数据库,以查找特定旅程中的所有段。 (例如,从A-> D的旅程可能具有段A-> B,B-> C,C-> D。)

我非常频繁地运行此查询,并且很快就完成了。数据库的索引方式是性能非常好。查询的代码如下:

public List<Segment> getSegmentsForUID(String trainUid) {
    Query segmentQuery = session.createQuery("select segment from Segment segment inner join segment.journey as journey where segment.journey " +
                                             "in (:journies) and journey.trainUid = '" + trainUid + "'");
    segmentQuery.setParameterList("journies", dailyJournies);
    queryCount++;
    return segmentQuery.getResultList();
}

在类的初始化中设置dailyJournies并且永远不会再次更改。

我的问题是,在多次执行此查询后(通常在2,000到3,000个查询之间)我总是收到: Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceededreturn segmentQuery.getResultList();

由于在启动后没有触及此类的其他部分,并且因为异常总是在这行上被抛出,所以我无法想象它在其他地方是一个问题。

经过一番挖掘后,我最初的想法是Hibernate会话变得太大,所以我开始关闭并在每1000次查询后重新打开会话,但这没有任何区别。我也尝试使用以下代码:

Cache cache = session.getSessionFactory().getCache();
cache.evictAllRegions();

要手动清除会话缓存,但这也没有做任何事情。

之前有没有其他人遇到过这种情况,或者有什么明显的东西让我失踪?

1 个答案:

答案 0 :(得分:0)

我以前似乎没有找到合适的信息。

显然这是其他人也经历过的问题(https://github.com/ow2-proactive/scheduling/issues/2870)。

对于任何绊倒这个问题的人,我通过在hibernate配置文件中添加以下两行来修复它:

<property name="hibernate.query.plan_cache_max_size">16</property>
<property name="hibernate.query.plan_parameter_metadata_max_size">128</property>

这是GitHub中的建议。我认为问题源于保持会话和sessionFactory为许多查询打开。我猜这个问题也可以通过为每1,000个条目创建一个新的sessionFactory来解决,但这个解决方案似乎更清晰。