SQLiteException:未知错误(代码 0):本机无法创建新字节 [] [英] SQLiteException: unknown error (code 0): Native could not create new byte[]

查看:70
本文介绍了SQLiteException:未知错误(代码 0):本机无法创建新字节 []的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试查询多达 30 个对象时遇到此错误,每个对象都有 字段字节[],其权重为 100x100 ARGB_8888 位图数据~39kb

I'm getting this error when trying to query up to 30 objects, each object has field byte[] which weights 100x100 ARGB_8888 bitmap data ~ 39kb

我使用的是 OrmLite 4.45 版本.在三星 GT n8000 平板电脑上(最大堆大小 64mb)

I'm using OrmLite 4.45 version. on a Samsung GT n8000 tablet (max heap size 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:

here's 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

  • 内存使用量增长如此之快正常吗?
  • 您如何看待将查询拆分为多个块并在这些单独的查询之间显式调用 System.gc()?
  • 谢谢!

    推荐答案

    内存使用量增长这么快正常吗?

    Is such fast growth of memory usage normal?

    不,不是.

    您如何看待将查询拆分为多个块并在这些单独的查询之间显式调用 System.gc()?

    What do you think about splitting query into chunks and explicitly calling System.gc() between those separate queries?

    不,这很可能无法解决问题.您需要直接解决底层内存问题.

    No, this most likely would not fix the issue. You need to resolve the underlying memory issue directly.

    在查看您未在帖子中提供的代码和实体后,这不是 ORMLite 问题,而是实体问题.

    After looking at your code and entities that you did not provide in your post, this is not a ORMLite issue but a entity problem.

    你有一个照片图库.每张照片都有一个可能很大的字节图像数据数组——可能是 50+k.问题是 Gallery 有一个急切的 Photo 外国集合:

    You have a Gallery of Photos. Each photo has a possibly large array of byte image data -- maybe 50+k. The problem is that the Gallery has an eager foreign collection of Photos:

    @ForeignCollectionField(eager = true)
    private ForeignCollection<Photo> photos;
    

    然后每个 Photo 都有其父 Gallery 的自动刷新版本.

    And then each Photo has an auto-refreshed version of its parent Gallery.

    @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = GALLERY)
    private Gallery gallery;
    

    这会设置一个急切的获取循环,导致 ORMLite 执行以下操作:

    This sets up an eager fetch loop which causes ORMLite to do something like the following:

    1. 每当 ORMLite 尝试将 Gallery 加载到内存中...
    2. 由于急切收集,它被要求执行另一个查询并将与画廊相关联的所有照片加载到内存中.
    3. 对于这些 Photo 实例中的每一个,由于自动刷新的父级,它被要求执行另一个查询以将关联的 Gallery 放入内存.
    4. 对于那个 Gallery,它被要求将所有 Photo 加载到内存中.
    5. ... ORMLite 实际上有一个转义,但仍然向下 3 个级别.
    1. Whenever ORMLite tries to load the Gallery into memory...
    2. it is being asked to do another query and load all of the photos associated with the Gallery into memory because of the eager collection.
    3. For each of those Photo instances, it is being asked to do another query to get the associated Gallery into memory because of the auto-refreshed parent.
    4. And for that Gallery it is asked to load all of the Photos into memory.
    5. ... ORMLite actually has an escape but still does this 3 levels down.

    ORMLite 没有 GalleryPhoto 实例的魔法视图,因此它将父 Gallery 附加到 中的外部字段照片s.如果你想要这个,那么我会看到下面的 ObjectCache 解决方案.

    ORMLite has no magic view of the Gallery and Photo instances so it attach the parent Gallery to the foreign field in the Photos. If you want this then I'd see the ObjectCache solution below.

    有多种方法可以解决此问题:

    There are a number of ways you can fix this:

    • 我建议不要使用foreignAutoRefresh = true.如果您需要照片的Gallery,那么您可以通过执行galleryDao.refresh(photo.getGallery()) 来获得它.这打破了急切获取链.
    • 你也可以让 photos 收藏变得急切.延迟加载的集合会更多次访问数据库,但也会打破循环.
    • 如果您真的必须拥有所有急切的集合和刷新,那么最好的解决方案是引入ObjectCache.您可能需要经常清除缓存,但每个 DAO 都会在缓存中查找并返回相同的对象实体,即使在进行急切获取循环的情况下也是如此.

    • I'd recommend not using foreignAutoRefresh = true. If you need the Gallery of a photo then you can get it by doing galleryDao.refresh(photo.getGallery()). This breaks the chain of eager fetches.
    • You could also make the photos collection not be eager. A lazy loaded collection would go more times to the database but would also break the cycle.
    • If you really must have all of the eager collection and refreshing then the best solution however would be the introduction of an ObjectCache. You may have to clear the cache often but each of the DAOs would then look in the cache and return the same object entity even with the eager fetch loop going on.

    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();
    

    这篇关于SQLiteException:未知错误(代码 0):本机无法创建新字节 []的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆