greenDAO icon indicating copy to clipboard operation
greenDAO copied to clipboard

android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=363 (# cursors opened by this proc=363)

Open zyh9018 opened this issue 6 years ago • 13 comments

android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=363 (# cursors opened by this proc=363)
at android.database.CursorWindow.<init>(CursorWindow.java:108)
at android.database.CursorWindow.<init>(CursorWindow.java:130)
at net.sqlcipher.CursorWindow.void <init>(boolean)(SourceFile:54)
at net.sqlcipher.database.SQLiteCursor.void fillWindow(int)(SourceFile:288)
at net.sqlcipher.database.SQLiteCursor.int getCount()(SourceFile:280)
at net.sqlcipher.AbstractCursor.boolean moveToPosition(int)(SourceFile:178)
at net.sqlcipher.AbstractCursor.boolean moveToFirst()(SourceFile:222)
at android.database.CursorWrapper.moveToFirst(CursorWrapper.java:65)
at org.greenrobot.greendao.AbstractDao.java.lang.Object loadUnique(android.database.Cursor)(SourceFile:166)
at org.greenrobot.greendao.AbstractDao.java.lang.Object loadUniqueAndCloseCursor(android.database.Cursor)(SourceFile:159)
at org.greenrobot.greendao.InternalQueryDaoAccess.java.lang.Object loadUniqueAndCloseCursor(android.database.Cursor)(SourceFile:41)
at org.greenrobot.greendao.query.Query.java.lang.Object unique()(SourceFile:130)
at org.greenrobot.greendao.query.QueryBuilder.java.lang.Object unique()(SourceFile:479)

This exception happened when I calling queyBuilder().where(xxx).unique(); to query a data. Can anyone help with it? Thanks.

zyh9018 avatar Nov 15 '17 10:11 zyh9018

More information, I'm using SQLCipher for encryption of database files.

zyh9018 avatar Nov 16 '17 02:11 zyh9018

We didn't meet the exception when developing. It only happened after pushling in a few devices MI3, MI6, VIVO Y51A, VIVO Y66.

zyh9018 avatar Nov 17 '17 02:11 zyh9018

The error message indicates that you have many open Cursor classes: # Open Cursors=363 (# cursors opened by this proc=363). This likely lead to the out of memory issue.

Check in all places in your code that you call close() on Cursor classes after you no longer need them. -ut

greenrobot-team avatar Nov 20 '17 14:11 greenrobot-team

Hi, thanks for the reply. But I don't open any cursor myself. All I'm doing is call a query method daoSession.getUserDao().queryBuilder().where(UserDao.Properties.PeerId.eq(peerId)).unique(); and caused this.

zyh9018 avatar Nov 23 '17 02:11 zyh9018

I'm having the same problem. No direct usage of cursors but I still run into this exception from time to time.

awhlee avatar Nov 27 '17 16:11 awhlee

Alright, then are you calling .unique() inside a loop or many times at once, for example using multiple threads? In that case it is recommended to limit the number of concurrent calls, for example by using a thread pool. -ut

greenrobot-team avatar Nov 28 '17 12:11 greenrobot-team

Nope. My latest stack trace shows the exception in a service that launches a single thread per user in the app. There will not be more than 5-10 users in the app. Otherwise, there could be a background sync thread per user and maybe some DB work based on some user interaction but no crazy loops or concurrency going on.

My exception is from a query.list() call not a query.unique() call. In the list() code, I can see the Cursor being instantiated and then daoAccess.loadAllAndCloseCursor(cursor) is called and this leads to a chain of calls that closes the cursor in a finally clause. Looks fine. So a bit miffed as to why this is happening. I wonder if there is a cursor leak but it is somewhere else and this code is just suffering because of it.

awhlee avatar Nov 28 '17 15:11 awhlee

Fatal Exception: 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:140) at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:134) at org.b.a.a.d(AbstractDao.java:453) at org.b.a.a.c(AbstractDao.java:203) at org.b.a.f.a(InternalQueryDaoAccess.java:37) at org.b.a.d.f.c(Query.java:89) at org.b.a.d.g.c(QueryBuilder.java:427)

I have same problem. Have an idea?

Reza-saeedi avatar Aug 18 '18 12:08 Reza-saeedi

I came across a tip from Stack Overflow that may help you find the cause. -ut

greenrobot-team avatar Aug 21 '18 11:08 greenrobot-team

i meet the same problem occurred when query sometimes. the key code is showed down mDaoMaster = new DaoMaster(recordOpenHelper.getWritableDb());//writer mDaoSession = mDaoMaster.newSession(); mBoxDoorTimesBeanDao = mDaoSession.getDeliverRecordBeanDao(); List<DeliverRecordBean> list = mBoxDoorTimesBeanDao.queryBuilder().where(condition, condition1).list();//query

is there has a relation with the problem using writeDao to query?

yahier avatar Mar 20 '19 06:03 yahier

Hi, thanks for the reply. But I don't open any cursor myself. All I'm doing is call a query method daoSession.getUserDao().queryBuilder().where(UserDao.Properties.PeerId.eq(peerId)).unique(); and caused this.

Same question. Have an idea?

boboqun avatar Oct 12 '21 01:10 boboqun

android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=363 (# cursors opened by this proc=363) at android.database.CursorWindow.<init>(CursorWindow.java:108) at android.database.CursorWindow.<init>(CursorWindow.java:130) at net.sqlcipher.CursorWindow.void <init>(boolean)(SourceFile:54) at net.sqlcipher.database.SQLiteCursor.void fillWindow(int)(SourceFile:288) at net.sqlcipher.database.SQLiteCursor.int getCount()(SourceFile:280) at net.sqlcipher.AbstractCursor.boolean moveToPosition(int)(SourceFile:178) at net.sqlcipher.AbstractCursor.boolean moveToFirst()(SourceFile:222) at android.database.CursorWrapper.moveToFirst(CursorWrapper.java:65) at org.greenrobot.greendao.AbstractDao.java.lang.Object loadUnique(android.database.Cursor)(SourceFile:166) at org.greenrobot.greendao.AbstractDao.java.lang.Object loadUniqueAndCloseCursor(android.database.Cursor)(SourceFile:159) at org.greenrobot.greendao.InternalQueryDaoAccess.java.lang.Object loadUniqueAndCloseCursor(android.database.Cursor)(SourceFile:41) at org.greenrobot.greendao.query.Query.java.lang.Object unique()(SourceFile:130) at org.greenrobot.greendao.query.QueryBuilder.java.lang.Object unique()(SourceFile:479)

This exception happened when I calling queyBuilder().where(xxx).unique(); to query a data. Can anyone help with it? Thanks.

请问有解决方案了吗?困扰我很久了,, 万分感谢!

boboqun avatar Oct 12 '21 03:10 boboqun

@boboqun Maybe there are too many open Cursors or the number of results for this query is too large?

Edit: Stack Overflow also suggests too many open Cursors: https://stackoverflow.com/a/15536202/9187282 Maybe you can use the suggested Strict Mode with detectLeakedSqlLiteObjects to find any leaked cursors.

greenDAO actually should close a Cursor after getting results, e.g. for unique() it will eventually call this: https://github.com/greenrobot/greenDAO/blob/2611b1c8d220953c1308131a225a0cf41dce3d1f/DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java#L157-L163

greenrobot-team avatar Oct 12 '21 05:10 greenrobot-team