sql >> Database teknologi >  >> RDS >> SQLite

SQLite-hukommelsesproblem med singleton-tilgang

Hvis du får en meddelelse, der angiver, at for mange filer er åbne, kan en årsag meget vel være, at der er for mange markører, der stadig er åbne.

Den returnerede besked er dog ikke altid den samme og er sandsynligvis specifik for den opgave/opkald, der kaldes.

I dette tilfælde var meddelelsen (kan ikke åbne databasefilen (kode 2062)) , endnu i et andet tilfælde (fra en SELECT var beskeden ikke i stand til at åbne databasefilen (kode 14) ). SQLite kan ikke åbne databasefil (kode 14) ved hyppig "SELECT"-forespørgsel.

Ovenstående link peger også på et indlæg, jeg lavede, som ganske tydeligt viser, at oprettelse af en markør resulterer i, at en fil (eller filer) åbnes.

Eksemplet gik gennem omkring 500 rækker, og for hver række blev der oprettet/genskabt 3 markører for hver række (så potentielt 1500+ markører, selvom der kun blev brugt 4 markørobjekter).

Til at begynde med lukkede det kun de 3 markører i slutningen (sidste række af overordnet af alle), hvilket resulterede i ikke i stand til at åbne databasefilen (kode 14) . At lukke de 3 markører for hver iteration løste problemet.

Den fejlede kode var :-

SQLiteDatabase db =getWritableDatabase(); Cursor shoplistcursor =getAllRowsFromTable(SHOPLIST_TABLE_NAME); Markør produktcsr; Markørgangecsr; 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();}

Mens den faste kode var:-

SQLiteDatabase db =getWritableDatabase(); Cursor shoplistcursor =getAllRowsFromTable(SHOPLIST_TABLE_NAME); Markør produktcsr; Markørgangecsr; 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))); } andet { productcsr.close(); aislecsr.close(); prdusecsr.close(); } } shoplistcursor.close(); db.close(); }

Jeg har en tendens til nu at følge følgende regel/praksis:-

  • Hvis man bare får resultatet f.eks. for at få antallet af rækker, skal du lukke markøren i metoden.

  • Hvis du bruger markøren til en visning, f.eks. en ListView, og luk derefter markøren i aktivitetens onDestroy metode.

  • Hvis du bruger markøren til, hvad jeg vil kalde mere kompleks behandling, f.eks. sletning af rækker med underliggende referencer, luk derefter markørerne, så snart de er færdige, inden for behandlingsløkken(e).



  1. Postgres dynamiske forespørgselsfunktion

  2. Forespørgselstimeout i pg-promise

  3. Hvordan kan jeg liste har samme id-data med while-løkke i PHP?

  4. Hvad sker der med den primære nøgle-id, når den overskrider grænsen?