首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OutOfMemoryError后恢复Hikaricp

OutOfMemoryError后恢复Hikaricp
EN

Stack Overflow用户
提问于 2020-08-27 16:50:07
回答 2查看 599关注 0票数 1

我有一个非常具体的场景,在执行查询期间,特别是在从db到结果集的取行过程中,我得到了一个OutOfMemoryError。

代码很简单,因为它:

代码语言:javascript
复制
public interface MyRepository extends Repository<MyEntity, Long> {

    @EntityGraph(value = "MyBigEntityGraphToFetchAllCollections", type = EntityGraphType.FETCH)
    @QueryHints({@QueryHint(name = "org.hibernate.readOnly", value = "true")})
    MyEntity getOneById(Long id);

}

public class MyService {

    ...

    public void someMethodCalledInLoop(Long id) {

       try{
           return repository.getOneById(id);
       } catch (OutOfMemoryError error) {
          // Here the connection is closed. How to reset Hikaricp?
          System.gc();
          return null;
       }

    }

}

看起来奇怪的是,getOne消耗了所有内存,但是由于急切地获取了大约80个集合,由于行的乘法,有些情况是无法支持的。

我知道我可以选择懒散地加载集合,但我不想这样做。每次加载时点击数据库1+N次数会消耗更多的时间,而我的应用程序却没有它。它是一批处理每毫安的记录,少于0,001%的记录在内存中产生了这种影响。所以我的策略是丢弃这几个记录,然后处理下一个记录。

捕获OutOfMemoryError之后,内存就被释放了,麻烦实体就变成了垃圾。但是由于此错误,HikariCP关闭(或被迫关闭)连接。

在方法的下一个调用中,hikaricp仍然给我一个封闭的连接。似乎是由于内存不足,hikaricp没有正确完成以前的事务,并且永远停留在这种状态。

我现在的目的是重置或恢复hikaricp我不需要关心使用池的其他线程。

因此,毕竟,我的简单问题是,如何在不重新启动应用程序的情况下,以编程方式重新启动或恢复原始状态。

谢谢,非常感谢看过这个的人。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-18 23:06:57

到目前为止,一切都不起作用。

我通过向该方法添加一个“查询提示”来最小化这个问题:

代码语言:javascript
复制
@QueryHints({@QueryHint(name = "org.hibernate.timeout", value = "10")})
MyEntity getOneById(Long id);

99%的结果集是在1秒或更短的时间内获取的,但有时结果集太大,花费的时间更长。这样,JDBC就会在内存受损之前停止获取结果。

票数 0
EN

Stack Overflow用户

发布于 2020-08-27 17:06:50

尝试将其添加到Hibernate配置中:

代码语言:javascript
复制
<property name="hibernate.hikari.connectionTestQuery">select 1</property>

这样,HikariCP将在将连接交给Hibernate之前测试连接是否仍然处于活动状态。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63620701

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档