当尝试查询最多 30 个对象时,我收到此错误,每个对象都有字段字节[]其权重为 100x100 ARGB_8888 位图数据~ 39kb
我使用的是 OrmLite 4.45 版本。在 Samsung GT n8000 平板电脑上(最大堆大小 64mb)
这是堆栈跟踪:
android.database.sqlite.SQLiteException: unknown error (code 0): Native could not create new byte[]
at android.database.CursorWindow.nativeGetBlob(Native Method)
at android.database.CursorWindow.getBlob(CursorWindow.java:403)
at android.database.AbstractWindowedCursor.getBlob(AbstractWindowedCursor.java:45)
at com.j256.ormlite.android.AndroidDatabaseResults.getBytes(AndroidDatabaseResults.java:161)
at com.j256.ormlite.field.types.ByteArrayType.resultToSqlArg(ByteArrayType.java:41)
at com.j256.ormlite.field.BaseFieldConverter.resultToJava(BaseFieldConverter.java:24)
at com.j256.ormlite.field.FieldType.resultToJava(FieldType.java:798)
at com.j256.ormlite.stmt.mapped.BaseMappedQuery.mapRow(BaseMappedQuery.java:60)
at com.j256.ormlite.stmt.SelectIterator.getCurrent(SelectIterator.java:270)
at com.j256.ormlite.stmt.SelectIterator.nextThrow(SelectIterator.java:161)
at com.j256.ormlite.stmt.StatementExecutor.query(StatementExecutor.java:187)
at com.j256.ormlite.dao.BaseDaoImpl.query(BaseDaoImpl.java:263)
at com.j256.ormlite.dao.EagerForeignCollection.(EagerForeignCollection.java:37)
at com.j256.ormlite.field.FieldType.buildForeignCollection(FieldType.java:781)
at com.j256.ormlite.stmt.mapped.BaseMappedQuery.mapRow(BaseMappedQuery.java:82)
at com.j256.ormlite.android.AndroidDatabaseConnection.queryForOne(AndroidDatabaseConnection.java:186)
at com.j256.ormlite.stmt.mapped.MappedQueryForId.execute(MappedQueryForId.java:38)
at com.j256.ormlite.field.FieldType.assignField(FieldType.java:540)
at com.j256.ormlite.stmt.mapped.BaseMappedQuery.mapRow(BaseMappedQuery.java:71)
at com.j256.ormlite.stmt.SelectIterator.getCurrent(SelectIterator.java:270)
at com.j256.ormlite.stmt.SelectIterator.nextThrow(SelectIterator.java:161)
at com.j256.ormlite.stmt.StatementExecutor.query(StatementExecutor.java:187)
at com.j256.ormlite.dao.BaseDaoImpl.query(BaseDaoImpl.java:263)
at com.j256.ormlite.stmt.QueryBuilder.query(QueryBuilder.java:319)
at com.j256.ormlite.stmt.Where.query(Where.java:485)
at com.j256.ormlite.dao.BaseDaoImpl.queryForEq(BaseDaoImpl.java:243)
这是日志猫:
05-16 14:05:24.561: D/dalvikvm(4163): GC_CONCURRENT freed 1247K, 10% free 18046K/19911K, paused 11ms+3ms, total 30ms
05-16 14:05:24.561: D/dalvikvm(4163): WAIT_FOR_CONCURRENT_GC blocked 10ms
05-16 14:05:24.686: D/dalvikvm(4163): GC_CONCURRENT freed 119K, 4% free 19922K/20743K, paused 11ms+2ms, total 28ms
05-16 14:05:24.686: D/dalvikvm(4163): WAIT_FOR_CONCURRENT_GC blocked 15ms
... whole ton of these
05-16 14:05:27.261: D/dalvikvm(4163): GC_CONCURRENT freed 109K, 2% free 62754K/63495K, paused 12ms+5ms, total 36ms
05-16 14:05:27.261: D/dalvikvm(4163): WAIT_FOR_CONCURRENT_GC blocked 20ms
05-16 14:05:27.366: I/dalvikvm-heap(4163): Clamp target GC heap from 65.738MB to 64.000MB
- 内存使用量增长如此之快正常吗?
- 您如何看待将查询拆分为块并在这些单独的查询之间显式调用 System.gc() ?
Thanks!
内存使用量增长如此之快正常吗?
不,不是。
您如何看待将查询拆分为块并在这些单独的查询之间显式调用 System.gc() ?
不,这很可能无法解决问题。您需要直接解决底层内存问题。
查看您的代码和您在帖子中未提供的实体后,这不是ORMLite http://ormlite.com/问题而是一个实体问题。
你有一个Gallery
of Photo
s。每张照片都有可能很大的字节图像数据数组——可能有 50+k。问题是Gallery
有大量的外国收藏Photo
s:
@ForeignCollectionField(eager = true)
private ForeignCollection<Photo> photos;
然后每个Photo
有其父级的自动刷新版本Gallery
.
@DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = GALLERY)
private Gallery gallery;
这会设置一个急切的获取循环,导致 ORMLite 执行如下操作:
- 每当 ORMLite 尝试加载
Gallery
进入记忆...
- 它被要求进行另一个查询并加载与该相关的所有照片
Gallery
因为急于收集而进入内存。
- 对于每一个
Photo
实例中,它被要求执行另一个查询来获取关联的Gallery
由于自动刷新父级而进入内存。
- 为此
Gallery
它被要求加载所有的Photo
进入内存。
- ... ORMLite 实际上有一个逃逸,但仍然降低了 3 个级别。
ORMLite 没有神奇的观点Gallery
and Photo
实例,因此它附加父级Gallery
到国外领域Photo
s。如果你想要这个那么我会看到ObjectCache
解决方案如下。
有多种方法可以解决此问题:
- 我会推荐not using
foreignAutoRefresh = true
。如果您需要Gallery
的照片然后你可以通过这样做得到它galleryDao.refresh(photo.getGallery())
。这打破了渴望获取的链条。
- 您还可以使
photos
收藏not渴望。延迟加载的集合会更多地访问数据库,但也会打破循环。
-
If you really必须拥有所有渴望收集和刷新的内容,那么最好的解决方案是引入ObjectCache
。您可能必须经常清除缓存,但每个 DAO 都会在缓存中查找并返回相同的对象实体,即使急切的获取循环正在进行。
galleryDao = getHelper().getRuntimeExceptionDao(Gallery.class);
galleryDao.setObjectCache(true);
photoDao = getHelper().getRuntimeExceptionDao(Photo.class);
photoDao.setObjectCache(true);
...
// if you load a lot of objects into memory, you must clear the cache often
galleryDao.clearObjectCache();
photoDao.clearObjectCache();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)