I have a large database I keep in memory on Android. There are a lot of rows and the size of the row is somewhat variable. How can I determine the size of the in-memory database at run-time?
-
possible duplicate of [Max size of an Android app's in-memory SQLite database?](http://stackoverflow.com/questions/3707694/max-size-of-an-android-apps-in-memory-sqlite-database) – madlymad Nov 30 '14 at 00:24
-
@madlymad , [Max size of an Android app's in-memory SQLite database?](http://stackoverflow.com/questions/3707694/max-size-of-an-android-apps-in-memory-sqlite-database) asks how large _can_ the database be. I am asking how large _is_ the database. – Jon Dec 01 '14 at 18:38
2 Answers
In SQLite, in-memory databases are implemented as a page cache without a backing file.
The SQLite C API allows to get the status with functions like sqlite3_db_status(SQLITE_DBSTATUS_CACHE_USED)
or sqlte3_status(SQLITE_STATUS_PAGECACHE_USED)
.
However, the Android database API does no give access to these functions.

- 173,858
- 17
- 217
- 259
OK, here is the solution I came up with. It isn't pretty, but it works.
Android's SQLiteDatabase
class includes a method that sets a maximum database size, setMaximumSize(long numBytes). The maximum size cannot be set below the current size. So the solution is to set the maximum size to the page file size and see what size the method returns. Here's the method in my SQLiteOpenHelper
class:
public synchronized int getDatabaseUsage() {
SQLiteDatabase db = getWritableDatabase();
long pageSize = db.getPageSize();
long savedMaximumSize = db.getMaximumSize();
long appliedSize = db.setMaximumSize(pageSize);
int percentageUsed = (int) ((appliedSize * 100) / savedMaximumSize);
db.setMaximumSize(savedMaximumSize);
Log.v(LOG_TAG, "Percentage database space used: " + percentageUsed);
return percentageUsed;
}
I set the max size to be the device's large memory class:
private static final long BYTES_IN_A_MEGABYTE = 1048576;
/**
* Maximum size of the database in bytes
*/
private final long mMaxSize;
public SQLHelper(Context context) {
super(context, null, null, DATABASE_VERSION);
mMaxSize = BYTES_IN_A_MEGABYTE * Helper.getLargeMemoryClass(context);
}
public void onCreate(SQLiteDatabase db) {
<database creation code>
db.setMaximumSize(mMaxSize);
}
Then I just check the database usage before every bulk insert. If the usage is above 50, I delete old rows from the table and run the vacuum command to recover space.
/**
* Rebuilds the entire database.
* <p/>
* This reclaims empty space left behind after deletions.
*/
public void vacuum(SQLiteDatabase db) {
db.execSQL("VACUUM");
}

- 9,156
- 9
- 56
- 73