当前位置: 首页 > 面试题库 >

处理大量元素时休眠不足的内存异常

宗政法
2023-03-14
问题内容

我正在尝试处理重量级元素(图像)的收集。集合的大小在8000-50000个条目之间变化。但是由于某种原因,在处理了1800-1900个条目之后,我的程序因java.lang.OutOfMemoryError:Java堆空间而掉线。

以我的理解,每次调用session.getTransaction()。commit()程序都应该释放堆内存,但是看起来它永远不会发生。我做错了什么?这是代码:

private static void loadImages( LoadStrategy loadStrategy ) throws IOException {
    log.info( "Loading images for: " + loadStrategy.getPageType() );

    Session session = sessionFactory.openSession();
    session.setFlushMode( FlushMode.COMMIT );
    Query query = session.createQuery( "from PageRaw where pageType = :pageType and pageStatus = :pageStatus and sessionId = 1" );
    query.setString( "pageStatus", PageStatus.SUCCESS.name() );
    query.setString( "pageType", loadStrategy.getPageType().name() );
    query.setMaxResults( 50 );

    List<PageRaw> pages;
    int resultNum = 0;

    do {

        session.getTransaction().begin();

        log.info( "Get pages statring form " + resultNum + " position" );
        query.setFirstResult( resultNum );
        resultNum += 50;
        pages = query.list();
        log.info( "Found " + pages.size() + " pages" );


        for (PageRaw pr : pages ) {
            Set<String> imageUrls = new HashSet<>();
            for ( UrlLocator imageUrlLocator : loadStrategy.getImageUrlLocators() ) {
                imageUrls.addAll(
                        imageUrlLocator.locateUrls( StringConvector.toString( pr.getSourceHtml() ) )
                );
            }

            removeDeletedImageRaws( pr.getImages(), imageUrls );
            loadNewImageRaws( pr.getImages(), imageUrls );
        }

        session.getTransaction().commit();

    } while ( pages.size() > 0 );

    session.close();
}

问题答案:

你混淆了 冲洗结算

  • 刷新 会话将针对数据库执行所有待处理的语句(它将内存中状态与数据库状态同步);

  • 清除 会话将清除会话(第一级)缓存,从而释放内存。

因此,您需要刷新 清除会话以恢复占用的内存。

除此之外,您还必须 禁用2级缓存 。否则,即使清除会话后,所有(或大多数)对象仍将保持可访问状态。



 类似资料:
  • 问题内容: 我有一个“复杂”的问题。 我正在使用Hibernate / JPA与数据库进行事务。 我不是DBA,客户端使用了我的应用程序,即RESTful Web服务。我的问题是数据库已更改(不是很频繁,但仍在更改)。另外,客户端并不总是尊重我的应用程序的输入(长度,类型等)。发生这种情况时,Hibernate会引发异常。异常很难翻译和从日志中读取,因为它具有嵌套的异常并且由很多文本组成:就像我说

  • 问题内容: 目前,我在 每个 Controller方法中 都 重复了以下代码: 这是正确的方法还是有更好的方法,也许在一个我可以引用的单独的类中?如果是这样,怎么办?每当我尝试将其放在单独的类中并从其他类中引用它时,它都会失败。 编辑 :我正在尝试使用尽可能少的外部库。如果Java在JDK中内置了ORM / JPA实现,我就不会使用Hibernate。 问题答案: 我本人已经遇到了很多次。通常,我

  • 我试图使用javax.crypto下的类和用于输入/输出的文件流来实现一个加密/解密程序。为了限制内存使用,我使用-xmx256m参数运行。 它可以很好地对较小的文件进行加密和解密。但是当解密一个巨大的文件(1G大小)时,会出现内存不足的异常: 编辑2: 通过更多的测试,它可以处理的最大文件大小约为堆大小的1/4。比如,如果设置-xmx256m,大于64m的文件将无法解密。

  • 问题内容: 我正在编写将Firebase中的元素附加到数组以使用文本字段执行简单搜索的代码。 该方法的代码如下: 我个人没有想到有可能发生很多事件的机会。我将无法将所有1000多个事件附加到字典中。那会刺痛我的记忆。无论如何,我可以让查询响应文本字段。也有人可以帮助我完成执行该操作但不会破坏我的记忆的查询行吗? 例如,我想提取有关使用查询搜索的事件的所有信息。因此,如果我开始输入“美国制造”,它将

  • 问题内容: 该程序一个接一个地执行数以万计的连续插入。我以前从未使用过Hibernate。我的性能变得非常慢(如果我只是手动连接并执行SQL,则速度会提高10-12倍。根据许多休眠教程,我的batch_size设置为50。 这是单个插入的日志-也许您可以帮助我准确了解正在发生的事情: 问题答案: 当您调用时,hibernate将生成一个INSERT SQL。该INSERT SQL将附加在刷新期间(