java - 当尝试关闭已读取许多对象的只读 session 时,Hibernate 因 OutOfMemory 失败

标签 java hibernate

当我提交关闭 session 时,当 recNos 数组很大(>20,000)时,此代码可能会失败并出现 OutOfMemory 异常。我只读取信息,并且一次只读取一个对象(想法是通过一次读取一个对象来减少内存负载),并且我只在循环中使用该对象进行调用,但我没有明确丢弃它。我是否做错了什么,我可以显式释放内存吗?

        try
        {
            session = com.jthink.songlayer.hibernate.HibernateUtil.getSession();
            for (Integer next : recNos)
            {
                Song song = SongCache.loadSongFromDatabase(session, next);
                folderToSongIds.put(new File(song.getFilename()).getParent(),song.getRecNo());
            }
        }
        finally
        {
            HibernateUtil.closeSession(session);
        }

这是堆栈跟踪

java.lang.OutOfMemoryError: GC overhead limit exceeded
at org.hibernate.internal.util.collections.IdentityMap.entryArray(IdentityMap.java:165)
at org.hibernate.internal.util.collections.IdentityMap.concurrentEntries(IdentityMap.java:76)
at org.hibernate.engine.internal.StatefulPersistenceContext.clear(StatefulPersistenceContext.java:237)
at org.hibernate.internal.SessionImpl.cleanup(SessionImpl.java:651)
at org.hibernate.internal.SessionImpl.close(SessionImpl.java:363)
at com.jthink.songlayer.hibernate.HibernateUtil.closeSession(HibernateUtil.java:94)

最佳答案

完成后,您可以通过调用 evict 将实体从 session 中分离出来:

    {
        Song song = SongCache.loadSongFromDatabase(session, next);
        folderToSongIds.put(new File(song.getFilename()).getParent(),song.getRecNo());
        session.evict(song);
    }

关于java - 当尝试关闭已读取许多对象的只读 session 时,Hibernate 因 OutOfMemory 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25095555/

相关文章:

java - JPA @OneToMany + @JoinColumn 删除引用表上的更新问题

java - 带有类名的 JPA/Hibernate 查询?

java - hibernate 中的一级缓存存储在哪里?在内存还是硬盘?

java - org.hibernate.validator.Length 最大值

java - 将 Mysql 转换为 Sqlite 数据库

java - 在 Windows 中使用 Java 为文本着色

java - 在许多枚举结构上循环时重构和删除 'for' 语句

java - 如何跳过所有集成测试 (-DskipITs) 和一个单元测试 mvn 命令行

java - Hibernate 在外键字段中插入空值

hibernate - 缓存中未找到查询结果