sql >> Database >  >> RDS >> SQLite

SQLite-geheugenprobleem met singleton-aanpak

Als u een melding krijgt dat er te veel bestanden zijn geopend, kan een oorzaak zijn dat er te veel cursors nog open zijn.

Het geretourneerde bericht hoeft echter niet altijd hetzelfde te zijn en is waarschijnlijk specifiek voor de taak/oproep die wordt aangeroepen.

In dit geval was het bericht (unable to open database file (code 2062)) , nog in een ander geval (van een SELECT was het bericht unable to open database file (code 14) ). SQLite kan databasebestand (code 14) niet openen bij frequente "SELECT"-query.

De bovenstaande link verwijst ook naar een bericht dat ik heb gemaakt, wat heel duidelijk laat zien dat het maken van een cursor ertoe leidt dat een bestand (of bestanden) wordt geopend.

Het voorbeeld liep door ongeveer 500 rijen en voor elke rij werden 3 cursors voor elke rij gemaakt / opnieuw gemaakt (dus mogelijk 1500+ cursors, hoewel er slechts 4 cursorobjecten werden gebruikt).

Aanvankelijk sloot het alleen de 3 cursors aan het einde (laatste rij van de bovenliggende van alle) resulterend in de unable to open database file (code 14) . Het sluiten van de 3 cursors voor elke iteratie loste het probleem op.

De code die mislukte was:-

        SQLiteDatabase db = getWritableDatabase();
        Cursor shoplistcursor = getAllRowsFromTable(SHOPLIST_TABLE_NAME);
        Cursor productcsr;
        Cursor aislecsr;
        Cursor prdusecsr;
        while(shoplistcursor.moveToNext()) {
            productcsr = getProductFromProductId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            aislecsr = getAisleFromAisleId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)));
            prdusecsr = getProductUsage(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)),
                    shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            if (productcsr.getCount() < 1 | aislecsr.getCount() < 1 | prdusecsr.getCount() < 1) {
                deleteShopListEntry(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_ID)));
            } 
            if(shoplistcursor.isLast()) {
                prdusecsr.close();
                aislecsr.close();
                productcsr.close();
            }
        }
        shoplistcursor.close();
        db.close();
}

Terwijl de vaste code was:-

        SQLiteDatabase db = getWritableDatabase();
        Cursor shoplistcursor = getAllRowsFromTable(SHOPLIST_TABLE_NAME);
        Cursor productcsr;
        Cursor aislecsr;
        Cursor prdusecsr;
        while(shoplistcursor.moveToNext()) {
            productcsr = getProductFromProductId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            aislecsr = getAisleFromAisleId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)));
            prdusecsr = getProductUsage(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)),
                    shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            if (productcsr.getCount() < 1 | aislecsr.getCount() < 1 | prdusecsr.getCount() < 1) {
                productcsr.close();
                aislecsr.close();
                prdusecsr.close();
                deleteShopListEntry(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_ID)));
            } else {
                productcsr.close();
                aislecsr.close();
                prdusecsr.close();
            }
        }
        shoplistcursor.close();
        db.close();
    }

Ik heb de neiging om nu de volgende regel/praktijk te volgen:-

  • Als u alleen het resultaat krijgt, b.v. om het aantal rijen te krijgen, sluit u de cursor in de methode.

  • Als u de cursor gebruikt voor een weergave, b.v. a ListView en sluit vervolgens de cursor in onDestroy van de activiteit methode.

  • Als u de cursor gebruikt voor wat ik meer complexe verwerking noem, b.v. verwijder rijen met onderliggende verwijzingen en sluit de cursors zodra ze klaar zijn, binnen de verwerkingslus(sen).



  1. Hoe de gegevens in unicode in hindi-taal op te slaan?

  2. RAC installeren voor een database met gegevensbestanden

  3. Histogram maken in PostgreSQL

  4. Berekeningen doen in MySQL versus PHP