Android SQLite游标是否一次将所有记录加载到内存中?



Android SQLite游标是否将查询的所有数据加载到内存中,或者是否有某种优化策略是其实现的一部分?

SQLiteCursor会在您浏览时用数据填充"窗口"。我的记忆是窗口大小为1MB,但我无法指出支持该记忆的特定代码。因此,对于小型查询,实际效果是,一旦开始访问行和列,SQLiteCursor将在内存中保存整个结果集。

感谢CommonsWare关于Window术语,所以我通过导航这些类SQLiteCursor -> AbstractWindowedCursor -> CursorWindow再次逆转Android。下面是CursorWindow的构造函数:

 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);
    }

可以看到,sCursorWindowSize是CommonsWare提到的大小:

sCursorWindowSize = Resources.getSystem().getInteger(
                com.android.internal.R.integer.config_cursorWindowSize) * 1024;

因为我当前的版本是Android SDK 23.0.1,所以com.android.internal.R.integer.config_cursorWindowSize的值是2048。意思是2MB。我没有另一个版本SDK用于检查。

Cursor不包含内存中的所有结果,但它确实包含返回查询的总数(通过getCount)。当你迭代的结果,它获取条目(不是一个接一个我猜,但可能在块)。我很确定在这个层面上有优化。一旦你完成了它,你必须关闭它,否则为什么系统会在查询已经完成后保持它打开。

最新更新