休眠,保存 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 实体,消耗大量内存的主要内容,如果未能解决你的问题,请参考以下文章
为啥当我从express发送一个简单的文件时,客户端会消耗大量内存?