Android Java:OutOfMemory,同时将巨大的List插入数据库SQL

Android Java:OutOfMemory,同时将巨大的List插入数据库SQL,第1张

概述我只是在一个使用ORMgreendao的Android项目上工作.它允许我一次(一次交易)将许多实体(显然是对象)插入数据库.在实践中有一种方法insertOrReplaceInTx(…)给定一个对象列表,它以一个集合作为参数.问题是我的列表中有12000个对象,并且插入内容有时会导致OutOfMemory异常.我正在考

我只是在一个使用ORM greendao的Android项目上工作.它允许我一次(一次交易)将许多实体(显然是对象)插入数据库.在实践中有一种方法

insertOrReplaceInTx(…)

给定一个对象列表,它以一个集合作为参数.问题是我的列表中有12000个对象,并且插入内容有时会导致OutOfMemory异常.我正在考虑一种解决问题并防止将来发生OOM的明智方法.我想到的唯一想法是将巨大的集合划分为一些子集合(每个假设500个元素),并在一个循环中进行提交,从而使多个小的提交而不是一个小的提交.不好的是,它需要更长的时间插入记录,并且时间很重要.最后,我不确定在提交之后进行提交是否仍然不会杀死堆.也许在两者之间调用sleep()方法来让GC清除堆…但是在我看来,这是一种丑陋的解决方案.

您身边有什么聪明的主意吗?
提前致谢

解决方法:

我正在使用greendao 1.3.1进行项目.一些表包含大约200000个实体(不包含很多属性).

我从csv中读取了实体,为了加快处理速度,我开发了一个小型解决方案,该解决方案也可能对您的OOM问题有所帮助.

解释:

greendao使用缓存,并且在每次插入后都会更新实体以获得行ID,并可能将实体插入其缓存中.如果您调用插入或更新方法并且还没有事务,那么最重要的一点就是启动事务.这减慢了“批量”插入的速度,增加了内存使用量,并降低了速度.

我做了什么:

表现(时间)

为了加快处理速度,我在进行任何插入 *** 作之前就开始了事务.这样,greendao不会在每个插入上启动事务,并且所有插入和更新都在同一个事务中,这在数据一致性方面具有其他好处.
您可以使用如下代码:

sqliteDatabase db = dao.getDatabase();db.beginTransaction();try {    // do all your inserts and so on here.    db.setTransactionSuccessful();} catch (Exception ex) {} finally {    db.endTransaction();}

但这还不能帮助您解决OOM问题.

内存使用情况

解决方案1

如果您不想弄乱greendao代码,可以不时发出一次DaoSession.clear().
这绝对是简单的解决方案,但性能将不如解决方案2.

解决方案2

为了防止greendao更新实体并将其插入到其缓存中,您可以使用AbstractDao.java中的以下代码替换方法private long executeInsert(T entity,sqliteStatement stmt):

/** * Insert an entity into the table associated with a concrete DAO. *  * @return row ID of newly inserted entity */public long insertOrReplace(T entity, boolean update) {    return executeInsert(entity, statements.getInsertOrReplaceStatement(), update);}private long executeInsert(T entity, sqliteStatement stmt) {    return executeInsert(entity, stmt, true);}private long executeInsert(T entity, sqliteStatement stmt, boolean update) {    long rowID;    if (db.isDbLockedByCurrentThread()) {        synchronized (stmt) {            bindValues(stmt, entity);            rowID = stmt.executeInsert();        }    } else {        // Do TX to acquire a connection before locking the stmt to avoID deadlocks        db.beginTransaction();        try {            synchronized (stmt) {                bindValues(stmt, entity);                rowID = stmt.executeInsert();            }            db.setTransactionSuccessful();        } finally {            db.endTransaction();        }    }    if (update) {        updateKeyAfterInsertAndAttach(entity, rowID, true);    }    return rowID;}
总结

以上是内存溢出为你收集整理的Android Java:OutOfMemory,同时将巨大的List插入数据库SQL全部内容,希望文章能够帮你解决Android Java:OutOfMemory,同时将巨大的List插入数据库SQL所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1094269.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存