【问题标题】:Is there any memory leak in the normal routine of sqlite3_*()?sqlite3_*()的正常例程中是否有内存泄漏?
【发布时间】:2010-04-26 08:23:35
【问题描述】:

sqlite3_prepare_v2() + sqlite3_step() + sqlite3_finalize() 的正常例程可能包含泄漏。

听起来很荒谬。但测试代码似乎说了算。或者我错误地使用了 sqlite3_*()。

感谢任何回复。

#include <stdio.h> 
#include <unistd.h>     // for usleep() 
#include <sqlite3.h> 


int multi_write (int j); 

sqlite3 *db = NULL; 

int main (void) 
{ 
    int ret = -1; 

    ret = sqlite3_open("test.db", &db); 
    ret = sqlite3_exec(db,"CREATE TABLE data_his (id INTEGER PRIMARY KEY, d1 CHAR(16))", NULL,NULL,NULL); 
    usleep (100000); 


    int j=0; 
    while (1) 
    { 
        multi_write (j++); 
        usleep (2000000); 
        printf ("   ----------- %d\n", j); 
    } 


    ret = sqlite3_close (db); 
    return 0; 
} 


int multi_write (int j) 
{ 
    int ret = -1; 

    char *sql_f = "INSERT OR REPLACE INTO data_his VALUES (%d, %Q)"; 
    char *sql = NULL; 

    sqlite3_stmt *p_stmt = NULL; 


    ret = sqlite3_prepare_v2 (db, "BEGIN TRANSACTION", -1, &p_stmt, NULL); 
    ret = sqlite3_step ( p_stmt ); 
    ret = sqlite3_finalize ( p_stmt ); 

    int i=0; 
    for (i=0; i<100; i++) 
    { 
        sql = sqlite3_mprintf ( sql_f, j*100000 + i, "00000000000068FD"); 

        ret = sqlite3_prepare_v2 (db, sql, -1, &p_stmt, NULL ); 
        sqlite3_free ( sql ); 
        //printf ("sqlite3_prepare_v2(): %d, %s\n", ret, sqlite3_errmsg (db)); 

        ret = sqlite3_step ( p_stmt ); 
        //printf ("sqlite3_step():       %d, %s\n", ret, sqlite3_errmsg (db)); 

        ret = sqlite3_finalize ( p_stmt ); 
        //printf ("sqlite3_finalize():   %d, %s\n\n", ret, sqlite3_errmsg (db)); 
    } 

    ret = sqlite3_prepare_v2 (db, "COMMIT TRANSACTION", -1, &p_stmt, NULL ); 
    ret = sqlite3_step ( p_stmt ); 
    ret = sqlite3_finalize ( p_stmt ); 


    return 0; 
}

并且我观察了由 top 运行的进程。

首先,内存统计是:

PID     PPID   USER     STAT   VSZ    %MEM  %CPU  COMMAND 
17731   15488  root     S      1104   5%    7%    ./sqlite3multiwrite 

main()的while(1){}中的printf()打印150时,内存统计为:

PID     PPID   USER     STAT   VSZ    %MEM  %CPU  COMMAND 
17731   15488  root     S      1552   5%    7%    ./sqlite3multiwrite 

听起来150个for-cycles后,sqlite3multiwrite使用的内存从1104KB增加到了1552KB。

这是什么意思?内存泄漏或其他东西?

【问题讨论】:

  • 用 valgrind 运行它会发生什么?
  • 你能粘贴一下valgrind的输出吗?

标签: c sqlite


【解决方案1】:

使用 Valgrind。从 1.1 MB 到 1.5 MB 的增长并不大,尤其是超过 150 次迭代。例如,SQLite 可以做一些缓存(它会提前预留一些内存)。

尝试更多迭代 - 可能存在您的程序无法增长的阈值。但是 Valgrind 是查找内存泄漏最准确的工具。

【讨论】:

  • 非常感谢!你是我在 stackoveflow.com 上的第一个回复者。 :) 因为我的系统只有 32M RAM。当 main() 的 while(1){} 中的 printf() 打印 161939 时,该进程被系统自动终止。所以听起来代码中存在真正的内存泄漏。并且当遮蔽 sqlite3_step() 时,进程的内存不会增加。这是一件令人困惑的事情。好像说 sqlite3_step() 有内存泄漏。
  • +1,此外,我发现 Valgrind 的 Massif 堆分析器工具在这种情况下非常有用。
【解决方案2】:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 2020-07-22
    • 2010-10-13
    • 2019-01-28
    • 2015-02-07
    相关资源
    最近更新 更多