zoukankan      html  css  js  c++  java
  • 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

    完。

  • 相关阅读:
    装饰器模式
    原型模式
    观察者模式
    Apollo 代码的编译演示
    Apollo 框架的剖析1
    gPRC学习笔记
    Docker入门
    ROS入门学习
    Mudo C++网络库第十一章学习笔记
    Mudo C++网络库第十章学习笔记
  • 原文地址:https://www.cnblogs.com/liyou-blog/p/5101955.html
Copyright © 2011-2022 走看看