在我的應用程序中,我使用CSVReader & hibernate將大量實體(如1 500 000或更多)從csv文件導入數據庫。代碼如下所示:在保存大量實體時,Hibernate會導致內存不足異常
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行),出現內存異常(堆空間)。
看來,這個問題在某種程度上與hibernate相關,因爲如果我只是註釋行session.save(current);它運行良好。如果未註釋,任務管理器將顯示javaw的內存使用量不斷增加,然後在某些時候解析會變得非常慢並且崩潰。
parseJournalHeader()
沒有什麼特別之處,它只是解析基於csv閱讀器給出的String[]
的實體。
你看起來像是在用清理會話的方式做正確的事情,應該清理內存問題......一個潛在的可能是第二級緩存,它不會被session.clear清空。它的設置是什麼......也許設置CacheMode.GET? – sMoZely 2011-05-26 10:13:31
無狀態會話在這裏可能很有用。在這裏閱讀無狀態會話的限制:http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/StatelessSession.html,如果它們在您的用例中不是問題,請嘗試使用它(通過sessionFactory.openStatelessSession()) – 2011-05-26 10:25:25