Cursor window allocation of 2048 kb failed. # Open Cursors=1 (# cursors opened by this proc=1)

15,393

This is looks the same issue as SQLite Android Database Cursor window allocation of 2048 kb failed

Your error says: "Open Cursors"

The answer in the above question explains it:

Most often the cause for this error are non closed cursors. Make sure you close all cursors after using them (even in the case of an error).

Cursor cursor = null;
try {
    cursor = db.query(...
    // do some work with the cursor here.
} finally {
    // this gets called even if there is an exception somewhere above
    if(cursor != null)
        cursor.close();
}
Share:
15,393
Shervin Gharib
Author by

Shervin Gharib

Updated on June 05, 2022

Comments

  • Shervin Gharib
    Shervin Gharib almost 2 years

    I'm making an Kiosk app that use database. The app is running all time in foreground. The app have many threads that using one shared DataBaseHelper instance. the app works flawlessly but most of the time after 5 or 6 hour, I encounter these exceptions then app crashes:

    E/DataBaseHelper﹕ Cursor window allocation of 2048 kb failed. # Open Cursors=1 (# cursors opened by this proc=1)

    E/CursorWindow﹕ Could not allocate CursorWindow '/data/user/0/com.kios.frm/databases/YadProjectDB.db' of size 2097152 due to error -24.

    E/SQLiteLog﹕ (14) cannot open file at line 30192 of [00bb9c9ce4]

    E/SQLiteLog﹕ (14) statement aborts at 16: [SELECT number FROM sms LIMIT 5] unable to open database file

    E/SQLiteQuery﹕ exception: unable to open database file (code 14);
    query: SELECT number FROM sms LIMIT 5

    E/SQLiteLog﹕ (14) os_unix.c:30192: (24)
    open(/data/user/0/com.kiosk.frm/databases/YadProjectDB.db-journal)-

    I closed cursor properly but still getting those exceptions. what are those exceptions? what is the cause of those exceptions?

    MainActivity

    private DataBaseHelper db = null; // Global     
    

    MainActivity onCreate method:

    db = new DataBaseHelper(this);
    
    new Thread(new Runnable() {
    @Override
    public void run() {
        while (threadRunningFlag) {
    
        Cursor result = null;
        try {
    
            result = db.getData("SELECT " + DataBaseHelper.SMS_COLUMN_PHONE_NUMBER  + " FROM " + DataBaseHelper.SMS_TABLE_NAME + " LIMIT 5");
            if (result != null && result.getCount() > 0) {
                while (!result.isAfterLast()) {
                    String phoneNumber = result.getString(result.getColumnIndex(DataBaseHelper.SMS_COLUMN_PHONE_NUMBER));
                    // ...
                    result.moveToNext();
                }
            }
        }catch (Exception e) {
            Log.e(TAG, "err->" + e.getLocalizedMessage());
    
        }finally {
            if (result != null) {
                result.close();
                result = null;
            }
        }
    
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Log.e(TAG, e.getMessage());
            }
        }
    }
    }).start();
    

    DataBaseHelper class:

    public class DataBaseHelper extends SQLiteOpenHelper {
    
        private static final int DATABASE_VERSION = 1;
        public static final String DATABASE_NAME = "YadProjectDB.db";
        public static final String SMS_TABLE_NAME = "sms";
        public static final String SMS_COLUMN_PHONE_NUMBER = "number";
        public static final String SMS_COLUMN_SMS_TEXT = "message";
    
        public static final String BLACK_LIST_TABLE_NAME = "blackList";
        public static final String BLACK_LIST_COLUMN_ID = "id";
        public static final String BLACK_LIST_COLUMN_PHONE_NUMBER = "number";
    
        private final String TAG = "DataBaseHelper";
    
        public DataBaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
    
        }
    
        @Override
        public void onCreate( SQLiteDatabase db ) {
            String command = "CREATE TABLE "
                    + SMS_TABLE_NAME
                    + "("
                    + SMS_COLUMN_PHONE_NUMBER + " TEXT,"
                    + SMS_COLUMN_SMS_TEXT + " TEXT,"
                    + ")";
            try {
                db.execSQL(command);
            }catch (Exception e) {
                Log.e(TAG, "err->" + e.getMessage());
            }
    
            command = "CREATE TABLE "
                    + BLACK_LIST_TABLE_NAME
                    + "("
                    + BLACK_LIST_COLUMN_PHONE_NUMBER + " TEXT,"
                    + ")";
            try {
                db.execSQL(command);
            }catch (Exception e) {
                Log.e(TAG, "err->" +  e.getMessage());
            }
        }
    
        public boolean insertToSms(String number, String message, String fileName, Integer uploadFlag, Integer blackList, Integer pictureFlag)
        {
            final SQLiteDatabase db = this.getWritableDatabase();
            ContentValues contentValues = new ContentValues();
            contentValues.put(SMS_COLUMN_PHONE_NUMBER, number);
            contentValues.put(SMS_COLUMN_SMS_TEXT, message);
            try {
                db.insert(SMS_TABLE_NAME, null, contentValues);
                return true;
            }catch (Exception e) {
                Log.e(TAG, "err->" + e.getMessage());
                return false;
            }
        }
    
        public Cursor getData(String query){
            final SQLiteDatabase db = getReadableDatabase();
            Cursor res = null;
            try {
                res = db.rawQuery(query, null);
                res.moveToFirst();
                return res;
            }catch (Exception e) {
                Log.e(TAG, "err->" + e.getMessage());
                if (res != null) {
                    res.close();
                    res = null;
                }
            }
            return null;
        }
    }
    
    • pskink
      pskink over 8 years
      what exactly do you want to achieve?
    • Shervin Gharib
      Shervin Gharib over 8 years
      cause of those exceptions and find the problem
    • pskink
      pskink over 8 years
      ok, why do you iterate over the Cursor?
    • Shervin Gharib
      Shervin Gharib over 8 years
      As you can see I'm retrieving data (like phoneNumber) of every rows.
    • pskink
      pskink over 8 years
      check for any leaks you have in your Activity: it seems that CursorWindow cannot be allocated because of low memory
    • pskink
      pskink over 8 years
      and why are you querying the db every second? it must be some flaw in your code logic...
    • Shervin Gharib
      Shervin Gharib over 8 years
      is it wrong to query db every second? in some threads i need to check data immediately.
    • pskink
      pskink over 8 years
      it is your own db so you know when anything is inserted / updated / deleted, dont you?
    • pskink
      pskink over 8 years
      "is it wrong to query db every second?" that's why i asked: what do you want to achieve actually?
  • Shervin Gharib
    Shervin Gharib over 8 years
    As you can see I'm closing Cursor properly
  • Byte Welder
    Byte Welder over 8 years
    And how about Cursors in other places in your application? You might be leaking them elsewhere.
  • Shervin Gharib
    Shervin Gharib over 8 years
    I'm using same code in other threads but with different logic. what about other exceptions?
  • Byte Welder
    Byte Welder over 8 years
    What other exceptions? Are you leaking any other data? There could be some kind of data that you keep in memory and keeps on growing until 5-6 hours when it becomes too much and your next allocation (the Cursor creation) fails.
  • Shervin Gharib
    Shervin Gharib over 8 years
    I'm populating db with incoming sms and do some operation on them. I tested app without any sms and empty db and again same exceptions occur.
  • Shervin Gharib
    Shervin Gharib over 8 years
    the exceptions are just related to db.