【发布时间】: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