Android Java:OutOfMemory,同时将巨大的List插入数据库SQL
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Android Java:OutOfMemory,同时将巨大的List插入数据库SQL,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2640字,纯文字阅读大概需要4分钟。
内容图文
![Android Java:OutOfMemory,同时将巨大的List插入数据库SQL](/upload/InfoBanner/zyjiaocheng/887/fd96487ee09a4c6caca025e2477c4fd8.jpg)
我只是在一个使用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所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。