2017-09-03 92 views
0

我有一個hibernate + java的問題。我有一個類需要一個文件,將其解析爲CSVRecord,然後通過processRecord()將每行轉換爲一個對象(classA),然後我嘗試在我的數據庫中查找該對象,如果我更新了對象「else」我第一次保存它。 處理1000行後,我提交事務,清理會話並重新開始事務。 問題是什麼時候開始處理文件(100萬條記錄)內存java消耗開始增長很多(2Gb),並在最後不釋放,所以如果我需要的方法處理另一個文件我沒有內存,我從來沒有遇到內存異常,因爲我仍然有內存,但在服務器中不會​​一樣。 我嘗試使用沖水()和清晰(),但沒有既不麥汁, 的代碼是這樣做同樣的代碼:休眠,節省1Millon實體,消耗大量內存

db = new DB(); 
db.open(); 
trn = db.session().beginTransaction(); 

for (CSVRecord line : lines) { 
     try { 
      if ((classA = processRecord(line)) != null) { 
      classB b = findObject(classA); 

      if (b != null) { 
       db.session().update(b); 
      } else { 
       db.session().save(classA); 
      } 

      if (recordNumber % 1000 == 0) { 
       trn.commit(); 
       db.session().clear(); 
       trn = db.session().beginTransaction(); 
      } 

      recordNumber++; 
      } 
     } catch (Exception e) { 
       e.printStackTrace(); 
     } 
} 

db.close(); 
+0

也許一個簡單的解決方案是隻處理1000每事務和關閉並啓動一個新的等。 –

+0

是的,我嘗試了它,它的工作原理很類似,但是這個想法並沒有被項目經理所接受,我也沒有因爲想打開和關閉數據庫太多時間而沮喪。 – Eber

+0

有在線解決方案,流式傳輸文件。我發現這個例如:http://www.baeldung.com/java-read-lines-large-file –

回答

0

使用無狀態會話,因爲它不具備持久性上下文緩存提高性能相比,你正在使用的方法

StatelessSession session = sessionFactory.openStatelessSession(); 
Transaction tx = session.beginTransaction(); 
for (int i=0; i<100000; i++) { 
    session.insert(yourentiry); 
} 
tx.commit(); 
session.close(); 
+0

當然,我要閱讀並嘗試它!明天我讓你知道它是如何的 – Eber

+0

可悲的是,沒有工作,仍然消耗大量的內存RAM ... – Eber