处理大量元素时,Hibernate内存不足异常

Yur*_*nko 5 java performance hibernate out-of-memory data-processing

我正在尝试处理重量级元素(图像)的集合.收集的大小在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();
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*nik 5

你把冲洗清算混淆了:

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

  • 清除会话会清除会话(第1级)缓存,从而释放内存.

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

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