2017-09-03 72 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