首先sqlite3内存增长的原因一般都是指针申请没有被回收,或者回收了后由于系统差异还需要清空缓存。
我们需要明确在sqlite3中的哪些指针是需要回收的,如下:
1、
char *zErrMsg = nullptr;
if (sqlite3_exec(db,sql,NULL,NULL,&zErrMsg) != SQLITE_OK)
{
qDebug()<<sqlite3_errmsg(db);
sqlite3_free(zErrMsg);
return false;
}
sqlite3_exec中的错误消息指针zErrMsg 需要回收,回收方法调用sqlite3_free。
2、
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(db,sql,-1,&stmt,NULL) != SQLITE_OK)
{
qDebug()<<sqlite3_errmsg(db);
sqlite3_finalize(stmt);
return false;
}
while (sqlite3_step(stmt) == SQLITE_ROW) {
//...
}
sqlite3_finalize(stmt);
执行了sqlite3_prepare_v2和sqlite3_step后的sqlite3_stmt 指针需要回收,回收方法调用sqlite3_finalize。
3、
char *zErrMsg = nullptr;
char **dbResult = nullptr;
if (sqlite3_get_table(db, sql, &dbResult, &nRow, &nColumn, &zErrMsg) != SQLITE_OK)
{
qDebug()<<sqlite3_errmsg(db);
sqlite3_free_table(dbResult);
sqlite3_free(zErrMsg);
return false;
}
sqlite3_free_table(dbResult);
sqlite3_free(zErrMsg);
执行了sqlite3_get_table后的zErrMsg 和dbResult 这两个指针都需要回收,回收方法sqlite3_free_table和sqlite3_free。
这里提供一个函数sqlite3_memory_used,通过它可以实时监测sqlite3申请的内存大小,如果内存在一直增大且没有回收,那么肯定某个地方没有对指针进行free。
但是有时候你观察sqlite3_memory_used大小没有变,但是通过指令top或者free你发现程序内存在增加且没有回收,这个时候可能只是系统没有对数据库的缓存进行回收,数据库为了能够快速增删改查,它会将数据加载到缓存中来进行提速。你可以调用如下指令清空缓存:
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
至于为什么是echo 3,如下解释:
0:是系统默认值,默认情况下表示不释放内存,由操作系统自动管理
1:释放页缓存
2:释放dentries和inodes
3:释放所有缓存