Skip to content

SQLCipherStatement.close() never closes its Cursor, leaking a CursorWindow per Room query #97

Open

Description

@langtind

SQLCipherStatement.close() sets closed = true and never closes the Cursor that step() created. Only reset() closes it:

public void reset() {
    if (cursor != null) {
        cursor.close();
        cursor = null;
    }
    stepped = false;
}

public void close() {
    closed = true;
}

Room 3 (androidx.room3 3.0.3) prepares, steps and closes a statement per query, and it never calls reset() before close(). So every query leaves a CursorWindow for the finalizer to free.

Versions: sqlcipher-android 4.18.0 through 4.19.1 and the current default branch, with Room 3.0.3 and SQLCipherDriver.

Measured: we ran 20,000 point reads of one 20 KB row through Room with SQLCipherDriver, on Android emulators, with no manual GC.

API 36 API 29
SQLCipherDriver as shipped +72 MB native heap +244 MB native heap
close() calling reset() first under 4 MB (0 KB after GC) under 4 MB

The framework's AndroidSQLiteDriver showed 24 KB over the same reads.

Workaround: we wrap the driver so that each statement's close() calls reset() first:

private class CursorClosingStatement(private val delegate: SQLiteStatement) : SQLiteStatement by delegate {
    override fun close() {
        delegate.reset()
        delegate.close()
    }
}

Suggested fix: in close(), close the cursor if it is open, as reset() does, before setting closed = true.

Activity

  1. developernotes commented on Oct 9, 2026

    @developernotes
    Member

    Hi @langtind,

    Great catch, thank you for the report. We will include a fix for this in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions