A normal routine of sqlite3_prepare_v2() + sqlite3_step() + sqlite3_finalize() could contain leak.
It sound ridiculous. But the test code seems to say it. Or I used the sqlite3_*() wrongly.
Appreciate for any reply.
#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;
}
And I watch the the process's run by top.
At first, the memory statistics is:
PID PPID USER STAT VSZ %MEM %CPU COMMAND
17731 15488 root S 1104 5% 7%开发者_如何学Go ./sqlite3multiwrite
When the printf() in while(1){} of main() prints the 150, the memory statistics is:
PID PPID USER STAT VSZ %MEM %CPU COMMAND
17731 15488 root S 1552 5% 7% ./sqlite3multiwrite
It sounds that after 150 for-cycles, the memory used by sqlite3multiwrite increase from 1104KB to 1552KB.
What does it mean? memory leak or other thing?
Use Valgrind. Growth from 1.1 MB to 1.5 MB is not that big, especially over 150 iterations. SQLite can, for example, do some caching (it reserves some memory in advance).
Try more itarations - maybe there is a threshold value over which your program cannot grow. But Valgrind is the most accurate tool for finding memory leaks.
I have get the key answer from http://old.nabble.com/Is-there-any-memory-leak-in-the-normal-routine--td28348648.html#a28354683
The sqlite3's cache is the reason, :)
精彩评论