sqlite3内存不断增加的原因

数据库是这样设计的:用内存保存数据,以提高增删查改的速度,同时把数据写入磁盘,让数据落地。
如果不删除数据库里的数据,随着数据不断地添加到数据库,数据库越来越大,RES内存也越来越大。

见测试代码a.c:

/*************************************************************************
    * File: a.cpp
    * Brief: 
    * Author: 
    * Created Time: Tue 05 Jan 2016 09:53:18 AM CST
 ************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include"sqlite3.h"

#define LOG_MSG(d,a,...) printf(a,##__VA_ARGS__)

sqlite3* m_SQLite3Conn=NULL;
int m_nextserial=0;
char m_sql[255];

int SQLiteExcute(const char* sql)
{
    if (NULL == m_SQLite3Conn || NULL == sql || strcmp(sql, "") == 0)
    {
        return -1;
    }
    char* err_msg = NULL;
    if(sqlite3_exec(m_SQLite3Conn,sql,NULL,NULL,&err_msg) != SQLITE_OK)
    {
        LOG_MSG(err_LogLevel,"sqlite3_exec fail.err=%s, sql=%s",err_msg,sql);
        sqlite3_free(err_msg);
        return -2;
    }
    int rows=sqlite3_changes(m_SQLite3Conn);
    sqlite3_free(err_msg);

    return rows;
}

int ainit()
{
    char* sql;
    sql="create table if not exists DeviceInfo("
        "serial TEXT PRIMARY KEY, "
        "ip TEXT, "
        "user TEXT, "
        "pwd TEXT);";
    SQLiteExcute(sql);
    sql="create index idxT1 on DeviceInfo(ip);";
    SQLiteExcute(sql);  
}

int aopen()
{
    int ret = sqlite3_open_v2("./db.db",&m_SQLite3Conn,
    SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX, 
    NULL);
    if(ret != SQLITE_OK){
        LOG_MSG(err_LogLevel,"open sqlite db failure[%s]", sqlite3_errmsg(m_SQLite3Conn));
        return -2;
    }
    ret=sqlite3_threadsafe();
    if (!ret)
    {
        LOG_MSG(err_LogLevel,"sqlite3 is not thread safe");
    }
    return 0;
}

int ainsert(char* ip,char* user,char* pwd)
{
    char id[255];
    sprintf(id,"id-%d",m_nextserial++);
    sprintf(m_sql, "insert into DeviceInfo(serial, ip, user, pwd) "
        "values('%s', '%s', '%s', '%s') ",
        id, ip, user, pwd);
    int ret=SQLiteExcute(m_sql);
    printf("id=%s
",id);
    return ret;
}

int adelete()
{
    char id[255];
    sprintf(id,"id-%d",m_nextserial-10);
    sprintf(m_sql, "delete from DeviceInfo where serial='%s' ", id);
    int ret=SQLiteExcute(m_sql);
    printf("delete id=%s
",id);
    return ret;
}

int main()
{
    aopen();
    ainit();
    printf("hello pid=%d
",getpid());
    usleep(10000*900);
    while(1)
    {
        ainsert("192.168.1.12","user2","pwd2");
        /*
        ---内存持续增加研究---
        
        原来,数据库是这样设计的:用内存保存数据,以提高增删查改的速度,同时把数据写入磁盘,让数据落地。
        如果不删除数据库里的数据,随着数据不断地添加到数据库,数据库越来越大,RES内存也越来越大。
        
        开启如下的删除数据库数据的功能代码后,虽然不断地有新数据添加到数据库,但也一直从数据库中删除着数据。
        数据库的数据总量一直保持10条数据的总量,VIRT、RES、SHR长期保存不变。
        
        所以,数据库里已经使用过的数据,应该尽量删除。
        或者,每次操作数据库的数据后,要关闭数据库连接,下一次要操作数据库的数据时,再打开连接。
        即重复如下逻辑:"打开数据->操作数据库数据->关闭数据库"。
        
        当然,数据库文件也要定期缩减。因为即使你删除了数据库的数据,sqlite3也不会自动缩减数据库。
        所以,需要定期执行sql缩减数据库文件命令:"vacuum;"。
        
        */
        //adelete();  //如果不注析此语句,内存会不断地增加;如果注析,内存一直保持稳定不变。
        usleep(2000);
    }
    return 0;
}

编译运行,使用如下命令查看进程内存情况,发现内存一直稳定不变。

top -p precessID

完成测试工程见:百度网盘软件源码 estsqlite.tar.gz

完。

原文地址:https://www.cnblogs.com/liyou-blog/p/5101955.html