Could not allocate CursorWindow
Asked Answered
A

3

19

I'm operating on an SQLite3 database in my android app. I just read from the pre populated database that has 200k rows and 14 columns. Entries are words. Datatype of all columns is text. Querying for words up to 11 letters (eg. ABANDONMENT) works fine. But for 12 or greater (eg. ABANDONMENTS), the app crashes. Here is the logcat:

Could not allocate CursorWindow '//data//data//com.example.myapp//databases//database.sqlite' of size 2097152 due to error -12.
threadid=11: thread exiting with uncaught exception (group=0x40adf9f0)
FATAL EXCEPTION: Thread-2883
android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=861 (# cursors opened by this proc=861)
at android.database.CursorWindow.<init>(CursorWindow.java:104)
at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:162)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:156)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:161)
at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:201)
at com.example.myapp.MainActivity.query(MainActivity.java:815)
at com.example.myapp.MainActivity$2.run(MainActivity.java:356)
at java.lang.Thread.run(Thread.java:856)

code:

query = "select * from words where col_1 = \"" + (myWord)+ "\";";
cursor = database.rawQuery(query, null);
if (cursor != null)                                          
    cursor.moveToFirst(); // line 815
if (!cursor.isAfterLast()) {
    do {
        for (i = 1; i < cursor.getColumnCount(); i++) {
            temp = cursor.getString(i);
            //other stuff
        }
    } while (cursor.moveToNext());
    cursor.close();
}

So what does the error mean and why is the app crashing?

Aglimmer answered 5/7, 2013 at 19:30 Comment(4)
The full code would be helpful. Are you closing the cursor after managing it yourself, also why not simply call cursor.moveToNext() instead of !cursor.isAfterLast()Hoyt
The full app code is 1000 lines. cursor.isAfterLast is used to check if the cursor has moved through all results and if it has I can stop.Aglimmer
Are you closing the cursor within the while loop ?Hoyt
No. Forgot to paste that line in the code above.Aglimmer
A
16

I was quering in a loop. And closing the cursor inside the loop and not outside solved the problem.

Aglimmer answered 5/8, 2013 at 14:56 Comment(0)
T
27

Error -12 means cursor leak.

Try to close it:

try {....} finally {  cursor.close();}
Tavares answered 14/1, 2014 at 8:17 Comment(1)
I use Kotlin use method, it automatically should close everything, so no, it's the problemHearing
A
16

I was quering in a loop. And closing the cursor inside the loop and not outside solved the problem.

Aglimmer answered 5/8, 2013 at 14:56 Comment(0)
O
7

Android cursors read all the query results into memory, and have a limit of 1 MB for that data.

This limit was chosen because this amount of data is likely to make your app run sluggishly on a mobile device.

You should, if possible:

  • do the computations not in your code but in SQL;
  • query only the data that you need (i.e., do not use SELECT * but get only the columns you need, and use a WHERE filter);
  • read the data in smaller portions.
Operculum answered 6/7, 2013 at 8:33 Comment(2)
That's not possible. All rows are unique in the table. So a query gives only a single result.Aglimmer
You are certainly getting more than one record. What is the result of the equivalent SELECT COUNT(*) ...?Operculum

© 2022 - 2024 — McMap. All rights reserved.