使用 Sqlite3内存增长原因复盘

问题还原

在做嵌入式产品时使用了Sqlite3的数据库,发现内存会异常增长,所有写了个Demo进行验证测试。此处仅提出个人的问题、分析和解决的方法,欢迎大神提出建议,共同进步。

CPU:A40i
架构:Cortex-A7
主频:1.2GHz
内存:2GB DDR3
ROM:8GB eMMC

创建表结构不在代码中体现,创建表方法:
CREATE TABLE Table_0_1 (
[Index] INTEGER PRIMARY KEY AUTOINCREMENT
UNIQUE,
Id INT NOT NULL,
Name TEXT (128) NOT NULL,
ValType INT NOT NULL,
Value TEXT (64),
Csq INT,
CreatedTime TIMESTAMP NOT NULL
DEFAULT (datetime(‘now’, ‘localtime’) )
);

#include <iostream>

#include <stdint.h>
#include <sqlite3.h>

using namespace std;

bool g_bAppExitFalge = true;

static void exitSignalCall(const int32_t nSig)
{
   g_bAppExitFalge = false;
}

static int32_t registerSignal(void)
{
   signal(SIGINT, exitSignalCall);
   signal(SIGKILL, exitSignalCall);
   signal(SIGTERM, exitSignalCall);

   return 0;
}

int main(int argc, char const *argv[])
{
   sqlite3 *pDb = NULL;

   registerSignal();

   int32_t nRet = sqlite3_open("./MySqlite.db", &pDb);
   if (SQLITE_OK != nRet) {
       cout << "Open err!!!" << endl;
       return -1;
   }

   char szSql[128] = "INSERT INTO Table_0_1 VALUES (1,'TagTest',10,'100',1)"&#xFF1B;

   while(g_bAppExitFalge) {

    nRet = sqlite3_exec(pDb, szSql, NULL, NULL, &errMsg);
       if (SQLITE_OK != nRet) {
           cout << "&#x6570;&#x636E;&#x63D2;&#x5165;&#x9519;&#x8BEF;:" << errMsg << endl;
           sqlite3_free(errMsg);
           errMsg = NULL;
       } else {
           if (errMsg) {
               cout << "&#x6267;&#x884C;&#x6B63;&#x5E38;:" << errMsg << endl;
               sqlite3_free(errMsg);
               errMsg = NULL;
           }
       }
       sleep(1);

   }

   sqlite3_close(pDb);

   return 0;
}
</sqlite3.h></stdint.h></iostream>

内存会不断增长,直至将内存耗尽;

问题分析

问题初期一直认为是Sqlite3库的问题,所有使用了更高版本的库,还是会出现该问题。所有将代码放到PC虚拟机中执行,发现不会出现内存泄露,会稳定在一个定值。所以分析可能的原因:

所以使用复合的SQL语句,代码如下:

#include <iostream>

#include <stdint.h>
#include <sqlite3.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>

using namespace std;

bool g_bAppExitFalge = true;

static void exitSignalCall(const int32_t nSig)
{
    g_bAppExitFalge = false;
}

/********************************************************************************************************************
 &#x51FD;&#x6570;&#x63CF;&#x8FF0;  : &#x6CE8;&#x518C;&#x4FE1;&#x53F7;&#x5904;&#x7406;&#x51FD;&#x6570;
 &#x53C2;    &#x6570;  : int32_t nSig: &#x89E6;&#x53D1;&#x4FE1;&#x53F7;
 &#x8FD4; &#x56DE; &#x503C;  : eSuccess: &#x6210;&#x529F;       &#x5176;&#x4ED6;:&#x5931;&#x8D25;
********************************************************************************************************************/
static int32_t registerSignal(void)
{
    signal(SIGINT, exitSignalCall);
    signal(SIGKILL, exitSignalCall);
    signal(SIGTERM, exitSignalCall);

    return 0;
}

int main(int argc, char const *argv[])
{

    sqlite3 *pDb = NULL;
    char *errMsg = NULL;
    int32_t nIndex = 199;

    registerSignal();

    int32_t nRet = 0;
    nRet = sqlite3_open("/extp/DefineTag.db", &pDb);
    if (SQLITE_OK != nRet) {
        cout << "Open err!!!" << endl;
        return -1;
    }

    printf("Open every one...\n");
    char szSql[2048] = "INSERT INTO Table_0_1 (Id,Name,ValType,Value,Csq) "
        "SELECT 1,'TagTest',10,'100',1 "
        "UNION ALL SELECT 2,'TagTest',10,'100',1 "
        "UNION ALL SELECT 3,'TagTest',10,'100',1 "
        "UNION ALL SELECT 4,'TagTest',10,'100',1 "
        "UNION ALL SELECT 5,'TagTest',10,'100',1 "
        "UNION ALL SELECT 6,'TagTest',10,'100',1 "
        "UNION ALL SELECT 7,'TagTest',10,'100',1 "
        "UNION ALL SELECT 8,'TagTest',10,'100',1 "
        "UNION ALL SELECT 9,'TagTest',10,'100',1 "
        "UNION ALL SELECT 10,'TagTest',10,'100',1 "
        "UNION ALL SELECT 11,'TagTest',10,'100',1 "
        "UNION ALL SELECT 12,'TagTest',10,'100',1 "
        "UNION ALL SELECT 13,'TagTest',10,'100',1 "
        "UNION ALL SELECT 14,'TagTest',10,'100',1 "
        "UNION ALL SELECT 15,'TagTest',10,'100',1 "
        "UNION ALL SELECT 16,'TagTest',10,'100',1 "
        "UNION ALL SELECT 17,'TagTest',10,'100',1 "
        "UNION ALL SELECT 18,'TagTest',10,'100',1 "
        "UNION ALL SELECT 19,'TagTest',10,'100',1 "
        "UNION ALL SELECT 20,'TagTest',10,'100',1;";

    while(g_bAppExitFalge) {

        nRet = sqlite3_exec(pDb, szSql, NULL, NULL, &errMsg);
        if (SQLITE_OK != nRet) {
            cout << "&#x6570;&#x636E;&#x63D2;&#x5165;&#x9519;&#x8BEF;:" << errMsg << endl;
            sqlite3_free(errMsg);
            errMsg = NULL;
        } else {
            if (errMsg) {
                cout << "&#x6267;&#x884C;&#x6B63;&#x5E38;:" << errMsg << endl;
                sqlite3_free(errMsg);
                errMsg = NULL;
            }
        }
        sleep(10);
    }

    printf("close success...\n");
    sqlite3_close(pDb);
    pDb = NULL;
    sleep(1);
    return 0;
}
</stdio.h></unistd.h></signal.h></sqlite3.h></stdint.h></iostream>

内存的消耗比V0.0版本的速度明显减慢,但是经过一晚上的运行,发现内存还是会增长。

针对于V1.0 版本的代码内存还是会增长的问题查资料,看到有人提出这样的分析,所有继续改良代码:

    ---&#x5185;&#x5B58;&#x6301;&#x7EED;&#x589E;&#x52A0;&#x7814;&#x7A76;---

    &#x539F;&#x6765;&#xFF0C;&#x6570;&#x636E;&#x5E93;&#x662F;&#x8FD9;&#x6837;&#x8BBE;&#x8BA1;&#x7684;&#xFF1A;&#x7528;&#x5185;&#x5B58;&#x4FDD;&#x5B58;&#x6570;&#x636E;&#xFF0C;&#x4EE5;&#x63D0;&#x9AD8;&#x589E;&#x5220;&#x67E5;&#x6539;&#x7684;&#x901F;&#x5EA6;&#xFF0C;&#x540C;&#x65F6;&#x628A;&#x6570;&#x636E;&#x5199;&#x5165;&#x78C1;&#x76D8;&#xFF0C;&#x8BA9;&#x6570;&#x636E;&#x843D;&#x5730;&#x3002;
    &#x5982;&#x679C;&#x4E0D;&#x5220;&#x9664;&#x6570;&#x636E;&#x5E93;&#x91CC;&#x7684;&#x6570;&#x636E;&#xFF0C;&#x968F;&#x7740;&#x6570;&#x636E;&#x4E0D;&#x65AD;&#x5730;&#x6DFB;&#x52A0;&#x5230;&#x6570;&#x636E;&#x5E93;&#xFF0C;&#x6570;&#x636E;&#x5E93;&#x8D8A;&#x6765;&#x8D8A;&#x5927;&#xFF0C;RES&#x5185;&#x5B58;&#x4E5F;&#x8D8A;&#x6765;&#x8D8A;&#x5927;&#x3002;

    &#x5F00;&#x542F;&#x5982;&#x4E0B;&#x7684;&#x5220;&#x9664;&#x6570;&#x636E;&#x5E93;&#x6570;&#x636E;&#x7684;&#x529F;&#x80FD;&#x4EE3;&#x7801;&#x540E;&#xFF0C;&#x867D;&#x7136;&#x4E0D;&#x65AD;&#x5730;&#x6709;&#x65B0;&#x6570;&#x636E;&#x6DFB;&#x52A0;&#x5230;&#x6570;&#x636E;&#x5E93;&#xFF0C;&#x4F46;&#x4E5F;&#x4E00;&#x76F4;&#x4ECE;&#x6570;&#x636E;&#x5E93;&#x4E2D;&#x5220;&#x9664;&#x7740;&#x6570;&#x636E;&#x3002;
    &#x6570;&#x636E;&#x5E93;&#x7684;&#x6570;&#x636E;&#x603B;&#x91CF;&#x4E00;&#x76F4;&#x4FDD;&#x6301;&#x4E00;&#x5B9A;&#x6570;&#x636E;&#x7684;&#x603B;&#x91CF;&#xFF0C;VIRT&#x3001;RES&#x3001;SHR&#x957F;&#x671F;&#x4FDD;&#x5B58;&#x4E0D;&#x53D8;&#x3002;

    &#x6240;&#x4EE5;&#xFF0C;&#x6570;&#x636E;&#x5E93;&#x91CC;&#x5DF2;&#x7ECF;&#x4F7F;&#x7528;&#x8FC7;&#x7684;&#x6570;&#x636E;&#xFF0C;&#x5E94;&#x8BE5;&#x5C3D;&#x91CF;&#x5220;&#x9664;&#x3002;
    &#x6216;&#x8005;&#xFF0C;&#x6BCF;&#x6B21;&#x64CD;&#x4F5C;&#x6570;&#x636E;&#x5E93;&#x7684;&#x6570;&#x636E;&#x540E;&#xFF0C;&#x8981;&#x5173;&#x95ED;&#x6570;&#x636E;&#x5E93;&#x8FDE;&#x63A5;&#xFF0C;&#x4E0B;&#x4E00;&#x6B21;&#x8981;&#x64CD;&#x4F5C;&#x6570;&#x636E;&#x5E93;&#x7684;&#x6570;&#x636E;&#x65F6;&#xFF0C;&#x518D;&#x6253;&#x5F00;&#x8FDE;&#x63A5;&#x3002;
    &#x5373;&#x91CD;&#x590D;&#x5982;&#x4E0B;&#x903B;&#x8F91;&#xFF1A;"&#x6253;&#x5F00;&#x6570;&#x636E;->&#x64CD;&#x4F5C;&#x6570;&#x636E;&#x5E93;&#x6570;&#x636E;->&#x5173;&#x95ED;&#x6570;&#x636E;&#x5E93;"&#x3002;

    &#x5F53;&#x7136;&#xFF0C;&#x6570;&#x636E;&#x5E93;&#x6587;&#x4EF6;&#x4E5F;&#x8981;&#x5B9A;&#x671F;&#x7F29;&#x51CF;&#x3002;&#x56E0;&#x4E3A;&#x5373;&#x4F7F;&#x4F60;&#x5220;&#x9664;&#x4E86;&#x6570;&#x636E;&#x5E93;&#x7684;&#x6570;&#x636E;&#xFF0C;sqlite3&#x4E5F;&#x4E0D;&#x4F1A;&#x81EA;&#x52A8;&#x7F29;&#x51CF;&#x6570;&#x636E;&#x5E93;&#x3002;
    &#x6240;&#x4EE5;&#xFF0C;&#x9700;&#x8981;&#x5B9A;&#x671F;&#x6267;&#x884C;sql&#x7F29;&#x51CF;&#x6570;&#x636E;&#x5E93;&#x6587;&#x4EF6;&#x547D;&#x4EE4;:"vacuum;"&#x3002;
#include <iostream>

#include <stdint.h>
#include <sqlite3.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>

using namespace std;

bool g_bAppExitFalge = true;

static void exitSignalCall(const int32_t nSig)
{
    g_bAppExitFalge = false;
}

/********************************************************************************************************************
 &#x51FD;&#x6570;&#x63CF;&#x8FF0;  : &#x6CE8;&#x518C;&#x4FE1;&#x53F7;&#x5904;&#x7406;&#x51FD;&#x6570;
 &#x53C2;    &#x6570;  : int32_t nSig: &#x89E6;&#x53D1;&#x4FE1;&#x53F7;
 &#x8FD4; &#x56DE; &#x503C;  : eSuccess: &#x6210;&#x529F;       &#x5176;&#x4ED6;:&#x5931;&#x8D25;
********************************************************************************************************************/
static int32_t registerSignal(void)
{
    signal(SIGINT, exitSignalCall);
    signal(SIGKILL, exitSignalCall);
    signal(SIGTERM, exitSignalCall);

    return 0;
}

int main(int argc, char const *argv[])
{

    sqlite3 *pDb = NULL;
    char *errMsg = NULL;
    int32_t nIndex = 199;

    registerSignal();

    int32_t nRet = 0;
    nRet = sqlite3_open("/extp/DefineTag.db", &pDb);
    if (SQLITE_OK != nRet) {
        cout << "Open err!!!" << endl;
        return -1;
    }

    printf("Open every one...\n");
    char szSql[2048] = "INSERT INTO Table_0_1 (Id,Name,ValType,Value,Csq) "
        "SELECT 1,'TagTest',10,'100',1 "
        "UNION ALL SELECT 2,'TagTest',10,'100',1 "
        "UNION ALL SELECT 3,'TagTest',10,'100',1 "
        "UNION ALL SELECT 4,'TagTest',10,'100',1 "
        "UNION ALL SELECT 5,'TagTest',10,'100',1 "
        "UNION ALL SELECT 6,'TagTest',10,'100',1 "
        "UNION ALL SELECT 7,'TagTest',10,'100',1 "
        "UNION ALL SELECT 8,'TagTest',10,'100',1 "
        "UNION ALL SELECT 9,'TagTest',10,'100',1 "
        "UNION ALL SELECT 10,'TagTest',10,'100',1 "
        "UNION ALL SELECT 11,'TagTest',10,'100',1 "
        "UNION ALL SELECT 12,'TagTest',10,'100',1 "
        "UNION ALL SELECT 13,'TagTest',10,'100',1 "
        "UNION ALL SELECT 14,'TagTest',10,'100',1 "
        "UNION ALL SELECT 15,'TagTest',10,'100',1 "
        "UNION ALL SELECT 16,'TagTest',10,'100',1 "
        "UNION ALL SELECT 17,'TagTest',10,'100',1 "
        "UNION ALL SELECT 18,'TagTest',10,'100',1 "
        "UNION ALL SELECT 19,'TagTest',10,'100',1 "
        "UNION ALL SELECT 20,'TagTest',10,'100',1;";

    while(g_bAppExitFalge) {

        nRet = sqlite3_exec(pDb, szSql, NULL, NULL, &errMsg);
        if (SQLITE_OK != nRet) {
            cout << "&#x6570;&#x636E;&#x63D2;&#x5165;&#x9519;&#x8BEF;:" << errMsg << endl;
            sqlite3_free(errMsg);
            errMsg = NULL;
        } else {
            if (errMsg) {
                cout << "&#x6267;&#x884C;&#x6B63;&#x5E38;:" << errMsg << endl;
                sqlite3_free(errMsg);
                errMsg = NULL;
            }
        }
        sleep(10);

#if 1
        nIndex++;
        if (nIndex > 200) {

            cout << "&#x5F00;&#x59CB;&#x6267;&#x884C;&#x5220;&#x9664;" << endl;
            nRet = sqlite3_exec(pDb, "DELETE FROM Table_0_1 "\
                "WHERE julianday('now', 'localtime')-julianday(CreatedTime) >= 0.05;", \
                NULL, NULL, &errMsg);
            if (SQLITE_OK != nRet) {
                cout << "&#x6267;&#x884C;&#x5220;&#x9664;&#x9519;&#x8BEF;:" << errMsg << endl;
                sqlite3_free(errMsg);
            } else {
                cout << "&#x6267;&#x884C;&#x5220;&#x9664;&#x6210;&#x529F;:" << endl;
            }

            cout << "&#x5F00;&#x59CB;&#x6267;&#x884C;VACUUM:" << endl;
            nRet = sqlite3_exec(pDb, "VACUUM;", NULL, NULL, &errMsg);
            if (SQLITE_OK != nRet) {
                cout << "&#x6267;&#x884C;VACUUM&#x9519;&#x8BEF;:" << errMsg << endl;
                sqlite3_free(errMsg);
            } else {
                cout << "&#x6267;&#x884C;VACUUM&#x6210;&#x529F;:" << endl;
            }
            nIndex = 0;
        }
#endif

    }

    printf("close success...\n");
    sqlite3_close(pDb);
    pDb = NULL;
    sleep(1);
    return 0;
}
</stdio.h></unistd.h></signal.h></sqlite3.h></stdint.h></iostream>

Original: https://blog.csdn.net/qinbo1234567890/article/details/123522480
Author: 古城码农
Title: 使用 Sqlite3内存增长原因复盘

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/815468/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球