Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 尝试关闭已读取多个对象的只读会话时,Hibernate因OutOfMemory而失败_Java_Hibernate - Fatal编程技术网

Java 尝试关闭已读取多个对象的只读会话时,Hibernate因OutOfMemory而失败

Java 尝试关闭已读取多个对象的只读会话时,Hibernate因OutOfMemory而失败,java,hibernate,Java,Hibernate,当我提交关闭会话时,当recNos数组较大(>20000)时,此代码可能会失败,并出现OutOfMemory异常。我只读取信息,一次只读取一个对象(其思想是通过一次读取一个对象来减少内存负载),我只在循环中使用该对象进行调用,但我没有明确地放弃它。如果我做错了什么,我可以显式释放内存 try { session = com.jthink.songlayer.hibernate.HibernateUtil.getSession();

当我提交关闭会话时,当recNos数组较大(>20000)时,此代码可能会失败,并出现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);
        }
这是stacktrace

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)

使用完实体后,可以通过调用execute将其从会话中分离:

    {
        Song song = SongCache.loadSongFromDatabase(session, next);
        folderToSongIds.put(new File(song.getFilename()).getParent(),song.getRecNo());
        session.evict(song);
    }
根据这篇文章,当GC无法清空堆的2%以上时会发生这种异常,我认为这可能意味着内存泄漏

看起来你正在写很多文件,这可能是内存泄漏的一个很好的来源。我不确定这些文件在创建后是否关闭

顺便说一句,我建议您使用内存分析器来查看占用堆的内容


**20%是我更新的打字错误

这可能是由于每次都创建新的文件实例造成的吗?加载的文件太多了?谢谢,听起来很可能是解决方案。你是说2%,它是一个文件对象,而不是一个文件编写器,所以没有什么可关闭的,但也许我可以使用路径,而不必首先构造文件。总之,我的答案是使用内存分析器。正如我提到的,我不知道你是如何创建文件的