我在尝试查询最多30个对象时遇到此错误,每个对象都有字段byte [] ,其权重为100x100 ARGB_8888位图数据 ~39kb < / p>
我使用的是OrmLite 4.45版本。在三星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)
这里的logcat:
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
谢谢!
答案 0 :(得分:2)
内存使用率如此快速增长是否正常?
不,不是。
您如何看待将查询分成块并在这些单独的查询之间显式调用System.gc()?
不,这很可能无法解决问题。您需要直接解决基础内存问题。
查看您在帖子中未提供的代码和实体后,这不是ORMLite问题,而是实体问题。
您有Gallery
个Photo
。每张照片都有一大堆字节图像数据 - 可能是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执行以下操作:
Gallery
加载到内存中时...... Gallery
相关联的所有照片加载到内存中。Photo
个实例,由于自动刷新的父级,系统会要求它执行另一个查询以将关联的Gallery
放入内存。Gallery
,系统会要求将所有Photo
加载到内存中。 ORMLite没有Gallery
和Photo
个实例的神奇视图,因此它将父Gallery
附加到Photo
s中的外部字段。如果你想要这个,那么我会在下面看到ObjectCache
解决方案。
您可以通过多种方式解决此问题:
foreignAutoRefresh = true
不。如果您需要照片的Gallery
,那么您可以通过galleryDao.refresh(photo.getGallery())
获取照片。这打破了一连串的渴望。photos
集合不渴望。延迟加载的集合会更多次访问数据库,但也会破坏循环。如果确实必须拥有所有热切的收集和刷新,那么最好的解决方案就是引入ObjectCache
。您可能必须经常清除缓存,但每个DAO都会查看缓存并返回相同的对象实体,即使正在进行eager fetch循环。
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();