sqlite3内存增长原因

原文链接https://blog.csdn.net/hexf9632/article/details/123546404
文章目录
1 背景
2 问题
3 排查
4 原因
5 解决方法
1 背景
嵌入式项目,故选用轻量级数据库 sqlite3;
通过 sqlite3 存储日志,日志数量较多,数据库文件大于500M;
嵌入式系统内存400M左右。
2 问题
在集成过程中出现如下问题:

通过 sqlite3_exec 函数不断往数据库中插入日志,内存占用不断增加;
通过 select count(*) from table_name获取日志的条数,内存迅速增大,增加的内存约等于数据库文件的大小。
开始一直以为是内存泄露了,不断排查程序,没有发现异常。

3 排查
针对问题1:

在网上有说是因为在执行 sqlite3_exec 之后没有通过 sqlite3_free 释放错误信息指针的原因,确实我当时也没加这个,所以加上这个释放函数,但是也并没有解决内存增加的问题,代码如下:

int ret = sqlite3_exec(pSqliteDb, pSqlBuf, NULL, NULL, &pErrmsg);
if (DB_OK != ret)
{
PrintWarn(“sqlite3 exec error, ret: %d, errmsg: %s\n”, ret, pErrmsg);
sqlite3_free(pErrmsg);
}
1
2
3
4
5
6
也有说通过 sqlite3_get_table 和 sqlite3_free_table 函数组合去实现可以避免内存增加的问题,但是我用这两个函数去替换也没起到效果。

针对问题2:

在网上有查到说通过 count(0) 和 count(1) 替换 count(*),如下:

select count(0) frome table_name
select count(1) frome table_name
1
2
无法解决。

也有说通过增加条件进行查找,如下:

selcet count() from table_name where ID > 0; / ID是我数据库表中的主键,自动增加的数值 */
1
也无法解决。

4 原因
后面通过 Free 命令发现其实内存增加是 Linux 的缓存在不断增加,实际程序使用的内存是不会一直增加的。这是由于 Linux 为了提高数据库的读写速度,会在读取数据库时,并且内存充足的情况下,将数据库的数据读到缓存中,所以会导致内存占用瞬间增加很多;而在插入数据时,也会将新插入的数据存到缓存中,从而导致内存占用不断增加。

如下图缓存占用的内存量就很大:

上述所说的这些其实是 Linux 内存管理机制引起的,其实并不会导致内存不够用的情况发生,因为在进程需要内存时,Linux 会释放掉部分缓存给进程使用,出于谨慎考虑,我又进行了如下测试进行验证:

设备内存400多M,我使用500M的数据库,直接去获取数据库的日志条数,不会导致内存崩溃,占用缓存大约200M;
写测试程序不断分配内存,将设备的内存占用到剩20M,然后去获取数据库的日志条数,不会导致内存崩溃,占用缓存少数,但是获取日志条数的时间增加比较多;
写测试程序不断分配内存,将设备的内存占用到剩下5M,然后不断插入日志到数据库,不会导致内存崩溃;
将数据库文件控制在350M左右,然后获取日志条数,使其占掉内存的大多数,接着写测试程序去不断分配内存,在内存被占满之后,会释放掉部分缓存给测试程序去使用;
通过测试读写大文件,也会出现跟数据库一样的问题。
5 解决方法
由上述测试结果可知,sqlite3 数据库的读写并不会导致内存泄露,而读写数据导致的内存占用不断增加,并不会引起内存问题,也不会引起内存不够用导致进程崩溃的问题,只是 Linux 内部的机制引起,通过内存占用增加去提高文件读写的效率,这无可厚非,在内存不够时,会自动去释放该部分的缓存,并不会导致内存崩溃,故不需要自己去处理。

如果非要去人为干预(不建议),也是有办法的,可以通过如下方法手动释放缓存:

Linux 释放内存的命令:

echo 1 > /proc/sys/vm/drop_caches
1
drop_caches 的值可以是 0-3 之间的数字,代表不同的含义:

0:不释放(系统默认值)
1:释放页缓存
2:释放 dentries 和 inodes
3:释放所有缓存
如果我们需要释放所有缓存,就输入下面的命令:

echo 3 > /proc/sys/vm/drop_caches
1
在释放缓存前需要先执行 sync,将缓存同步到文件中:

sync
1
释放完内存后改回去让系统重新自动分配内存:

echo 0 > /proc/sys/vm/drop_caches
1
总的步骤就是:

sync
echo 1 > /proc/sys/vm/drop_caches
echo 0 > /proc/sys/vm/drop_caches
————————————————
版权声明:本文为CSDN博主「半砖」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hexf9632/article/details/123546404

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值