【问题标题】:Hibernate causes out of memory exception when saving large number of entities保存大量实体时休眠导致内存不足异常
【发布时间】:2011-09-02 11:13:31
【问题描述】:

在我的应用程序中,我使用 CSVReader 和休眠将大量实体(如 1 500 000 或更多)从 csv 文件导入数据库。代码如下所示:

        Session session = headerdao.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        int count = 0;
        String[] nextLine;

        while ((nextLine = reader.readNext()) != null) {
            try {

                if (nextLine.length == 23
                        && Integer.parseInt(nextLine[0]) > lastIdInDB) {
                    JournalHeader current = parseJournalHeader(nextLine);
                    current.setChain(chain);
                    session.save(current);
                    count++;
                    if (count % 100 == 0) {
                        session.flush();
                        tx.commit();
                        session.clear();
                        tx.begin();
                    }
                    if (count % 10000 == 0) {
                        LOG.info(count);
                    }

                }

            } catch (NumberFormatException e) {
                e.printStackTrace();
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }
        tx.commit();
        session.close();

如果文件足够大(大约 700 000 行),我会出现内存不足异常(堆空间)。

似乎问题与休眠有关,因为如果我只注释行 session.save(current);它运行良好。如果未注释,任务管理器会显示 javaw 的内存使用量不断增加,然后在某些时候解析变得非常慢并且崩溃。

parseJournalHeader() 没有什么特别之处,它只是根据 csv 阅读器提供的 String[] 解析一个实体。

【问题讨论】:

  • 您看起来在清除会话方面做对了,这应该是解决内存问题...一种可能是二级缓存,它不会被会话清空。清除。它的设置是什么……也许是设置 CacheMode.GET?
  • 无状态会话在这里可能有用。在此处阅读无状态会话的限制:docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/…,如果它们在您的用例中不是问题,请尝试使用它(通过 sessionFactory.openStatelessSession())

标签: java hibernate csv heap-memory


【解决方案1】:

Session 实际上将对象保存在缓存中。您正在做正确的事情来处理一级缓存。但是还有更多的事情可以阻止垃圾收集的发生。

尝试改用 StatelessSession。

【讨论】:

  • 我尝试使用 StatelessSession 但结果相同。使用 Eclipse 内存分析器检查转储告诉我,6 个“com.mysql.jdbc.JDBC4PreparedStatement”是最大的泄漏嫌疑人。它们消耗了几乎所有的内存。这是否说明了问题?
  • 看来问题与 c3p0 缓存语句有关。我从 hibernate.cfg 中删除了 c3p0 配置并摆脱了内存问题。我会尝试进一步调查它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-07
  • 2012-09-09
  • 2012-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多