查询时出现间断的CursorWindowAllocationException

时间:2019-06-12 00:31:50

标签: android sqlite android-room

我有一个带有间歇性错误(具有相同数据集)的简单会议室数据库,有时在数据库上运行第一个查询时,它将因CursorWindowAllocationException而崩溃。

这种情况并非总是会发生,在大多数情况下,不会因完全相同的数据集而崩溃。

正在运行的查询是:

@Query("SELECT * FROM history")
LiveData<List<HistoryEntity>> getAllHistoryLiveData();

例外:

android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. 
    at android.database.CursorWindow.<init>(CursorWindow.java:108)
    at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
    at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:138)
    at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:132)
    at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:220)
    at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:259)
    at androidx.room.RoomOpenHelper.hasRoomMasterTable(RoomOpenHelper.java:156)
    at androidx.room.RoomOpenHelper.checkIdentity(RoomOpenHelper.java:124)
    at androidx.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:116)
    at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onOpen(FrameworkSQLiteOpenHelper.java:151)
    at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:349)
    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:238)
    at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:96)
    at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:54)
    at androidx.room.RoomDatabase.query(RoomDatabase.java:238)
    at uk.co.flakeynetworks.HistoryDao_Impl$7.compute(HistoryDao_Impl.java:416)
    at uk.co.flakeynetworks.HistoryDao_Impl$7.compute(HistoryDao_Impl.java:402)
    at androidx.lifecycle.ComputableLiveData$2.run(ComputableLiveData.java:101)

1 个答案:

答案 0 :(得分:1)

CursorWindow在Android中是数据库行的缓冲区,总计2MB,即2048kB。

引发的异常表明您的进程已经达到其分配的内存限制,因此无法使用或消耗额外的2MB内存。

您可以执行以下操作来解决此问题。

  1. 使用分页库获取您的数据块,而不是整个表的数据。

  2. 重新检查您的代码以查看是否存在导致进程内存消耗的内存泄漏

Here是一篇不错的中篇文章,其中详细说明了如何在Android上执行大型数据库查询