休眠,保存 1Millon 实体,消耗大量内存

Posted

技术标签:

【中文标题】休眠,保存 1Millon 实体,消耗大量内存【英文标题】:Hibernate, save 1Millon entities, consume A LOT of memory 【发布时间】:2017-09-03 13:30:43 【问题描述】:

我遇到了hibernate+java的问题。我有一个类,它获取一个文件,将其解析为 CSVRecord,然后通过 processRecord () 将每一行转换为一个对象(classA),然后我尝试在我的数据库中找到该对象,如果我更新了对象“else”我第一次保存它。 处理 1000 行后,我提交事务,清理会话并重新开始事务。 问题是当开始处理文件(100万条记录)时,java消耗的内存开始增长很多(2Gb)并且最后不释放,所以如果我需要该方法处理另一个我没有内存的文件,我从来没有内存异常,因为我还有内存,但在服务器中它不会是一样的。 我尝试使用flush()和clear()来做同样的代码,但都没有, 代码是这样的:

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();

【问题讨论】:

也许一个简单的解决方案是每笔交易只处理 1000 笔交易,然后关闭并开始一个新的交易等等。?? 是的,我试过了,有点效果,但是这个想法没有被项目经理接受,我也不喜欢这个想法,因为我也要打开和关闭数据库的许多倍。 网上有解决方案,流文件。例如,我发现了这个:baeldung.com/java-read-lines-large-file 谢谢你,我要去读这篇文章,但问题是没有读文件,那行得通,蚂蚁然后我尝试逐行阅读而不是使用CSVRecord,但还是一样。我认为我在提交或保存/更新时做错了。 【参考方案1】:

使用无状态会话,因为它没有持久性上下文缓存,与您当前使用的方法相比,它提高了性能

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

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

【讨论】:

我一定会阅读并尝试一下!明天我告诉你过得怎么样

以上是关于休眠,保存 1Millon 实体,消耗大量内存的主要内容,如果未能解决你的问题,请参考以下文章

flask如何使模板返回大文件,又不消耗大量内存

NSRunLoop 正在消耗大量的 cpu 和内存

为啥当我从express发送一个简单的文件时,客户端会消耗大量内存?

为啥在嵌入式 HSQLDB 上运行更新查询会消耗大量内存?

范围大时“for / range”会不会消耗大量内存? [复制]

spring boot 微服务在部署在 ecs aws 的容器中消耗大量内存