Reputation: 11470
Does an Android SQLite cursor load all data for a query into memory, or is there some sort of optimization strategy that's part of its implementation?
Upvotes: 13
Views: 4032
Reputation: 30304
Thanks for CommonsWare about Window
term so I reversed again Android by navigating those classes SQLiteCursor -> AbstractWindowedCursor -> CursorWindow
. Here is CursorWindow
constructor:
public CursorWindow(String name) {
mStartPos = 0;
mName = name != null && name.length() != 0 ? name : "<unnamed>";
if (sCursorWindowSize < 0) {
/** The cursor window size. resource xml file specifies the value in kB.
* convert it to bytes here by multiplying with 1024.
*/
sCursorWindowSize = Resources.getSystem().getInteger(
com.android.internal.R.integer.config_cursorWindowSize) * 1024;
}
mWindowPtr = nativeCreate(mName, sCursorWindowSize);
if (mWindowPtr == 0) {
throw new CursorWindowAllocationException("Cursor window allocation of " +
(sCursorWindowSize / 1024) + " kb failed. " + printStats());
}
mCloseGuard.open("close");
recordNewWindow(Binder.getCallingPid(), mWindowPtr);
}
As you can see, sCursorWindowSize
is the size that CommonsWare has mentioned:
sCursorWindowSize = Resources.getSystem().getInteger(
com.android.internal.R.integer.config_cursorWindowSize) * 1024;
As my current version is Android SDK 23.0.1
, the value of com.android.internal.R.integer.config_cursorWindowSize
is 2048. It means 2MB. I don't have another version SDK for checking.
Upvotes: 13
Reputation: 1629
Cursor doesn't contain all the results in memory but it does have the total count of the returned query (via getCount). While you iterate over the results it fetches the entries (not one by one I guess but probably in chunks). I'm pretty sure there are optimizations on this level. Once you're done with it you must close it - otherwise why would the system keep it open after the query has been already made.
Upvotes: 4
Reputation: 1007658
A SQLiteCursor
fills a "window" with data as you navigate through it. My recollection is that the window size is 1MB, but I can't point you to specific code that backs up that recollection. So, for small queries, the net effect is that the SQLiteCursor
will hold the entire result set in memory, once you start accessing rows and columns.
Upvotes: 13