Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QSqlQuery Memory issues. QSqlQuery::exec() and QSqlDatabase::open()/close();

Tags:

c++

sqlite

qt

I'm checking the memory usage of an application I've made. It makes numerous calls to read and write values to and from a database (SQLite 3). I've observed the following:

  • QSqlQuery::exec() uses some KB of RAM to execute a given query, but does not release the memory after it goes out of scope.

  • QSqlDatabase:: open() & close() do not help free resources as the documentation suggest. If anything, close() causes resources (at least memory) to remain 'trapped' on the heap/stack.

For example, here is a typical segment of code I've been using to access my database.

QStringList values;
db.open();
QString strQuery = "SELECT DISTINCT " + field + " FROM " + table + str;

QSqlQuery query(db);
query.prepare(strQuery);

if(query.exec() == true)
{
  while(query.next())
  {
    values.push_back(query.value(0).toString());
  }
}

db.close();

Having experimented with I find the code below 'traps' less memory:

QStringList values;
QString strQuery = "SELECT DISTINCT " + field + " FROM " + table + str;

QSqlQuery query(strQuery, db);

  while(query.next())
  {
    values.push_back(query.value(0).toString());
  }

However, a small amount of memory is still not released. Has anyone else experienced anything like this?

Can I some how release this memory?

P.s. Same happens here, some memory is never released:

db.open();
QSqlQuery query(db);

query.exec("DELETE FROM table1");
query.exec("DELETE FROM table2");
query.exec("DELETE FROM table3");
query.exec("DELETE FROM table4");
...

db.close();
like image 685
nf313743 Avatar asked Jul 14 '11 08:07

nf313743


2 Answers

It seems that in order to release this memory you must create the QSqlQuery variable as a pointer, and delete this pointer before you close the database:

QStringList values;
db.open();
QString strQuery = "SELECT DISTINCT " + field + " FROM " + table + str;

QSqlQuery *query = new QSqlQuery(db);
query->prepare(strQuery);

if(query->exec() == true)
{
  while(query->next())
  {
    values.push_back(query->value(0).toString());
  }
}

delete query;
db.close();

The memory is then released after the database closes.

like image 141
nf313743 Avatar answered Sep 23 '22 03:09

nf313743


You have to use QSqlQuery.finish () or QSqlQuery.clear before you close the database. Otherwise residual memory is left out in the Query object. It is mentioned in the document that Query object can be used for multiple query. You will noticed the "memory leak".. when you query for 10,000 records. The memory usage goes up drastically.

like image 25
Rav Avatar answered Sep 24 '22 03:09

Rav