在HTC Desire上运行我的应用程序(android版本2.3.3)我注意到在调用以下函数时内存使用量增加:
private static final String TABLE_MODULES = "tbl_module1";
private static final String MOD1_INCLUDE = "mod1_include";
private void setItemInclude (int idx, boolean include)
{
String incString = "";
if (include)
incString = "true";
else
incString = "false";
ContentValues args = new ContentValues();
args.put(MOD1_INCLUDE, incString);
database.update(TABLE_MODULES,args,"_id="+idx,null);
}
其中,数据库的类型为SQLiteDatabase,并且是从对dbHelper.getWritableDatabase()的调用中获取的,其中dbHelper是从SQLiteOpenHelper派生的,并使用应用程序上下文进行实例化。
我得到了所需的更新,但是当我检查应用程序的数据使用情况时,每次调用似乎增加了大约60KB,除非调用dbHelper.close(),否则不会释放。多次调用此函数会导致SQLiteDiskIOException。
我尝试过database.rawQuery()
,它也会正确更新,但同样会挂在内存上。
String updateQuery = "UPDATE " + TABLE_MODULES + " SET MOD1_INCLUDE = " + "'" + incString + "'" + " WHERE _id ='" + idx + "'";
Cursor cursor = database.rawQuery(updateQuery, null);
cursor.moveToFirst();
cursor.close();
在华硕(Android 4.0.3)和Orange旧金山(android 2.1.update1)上运行相同的代码没有这个问题。
从活动getWritableDatabase
调用 onCreate()
,结果数据库在onDestroy()
中关闭。我认为在活动期间保持数据库打开是可以的。关于什么是原因的任何想法?
答案 0 :(得分:0)
我找到了导致问题的原因。
在HTC上,每次调用database.update()
时,临时文件都会在应用程序的数据库目录中更新。此文件的扩展名为 .sqlite-wal 。此文件在每次调用时变大(60KB),仅在关闭数据库时删除。
华硕还会创建一个临时文件,但扩展名为 .sqlite-journal 。此文件也会在每次update()
调用时更新,但一旦事务完成,文件的大小将减小为零。因此,不会导致内存问题。
我不确定Journal和Wal之间的区别是什么,但他们认为它们都是在事务失败后回滚数据库。我已使用以下代码解决了内存问题,该代码关闭了日志/沃尔玛功能。
Cursor cursor = database.rawQuery("PRAGMA journal_mode=OFF", null);
cursor.moveToFirst();
cursor.close();
打开数据库后调用此选项似乎可以防止创建这些临时文件。
但是,我不相信这是一个好主意。我很惊讶没有发现其他人报告这个问题,并想知道是否将数据库打开为多个交易做好准备被认为是不好的做法?我是SQL新手,对数据库的经验相当有限。
答案 1 :(得分:0)
documentation非常清楚。
WAL日记记录模式使用预写日志而不是回滚 期刊实施交易。
在您的情况下,听起来automatic checkpointing未配置或无法正常工作。您可能不希望关闭日记功能,因为它可能会导致数据丢失。