QSqlQuery内存问题。 QSqlQuery :: exec()和QSqlDatabase :: open()/ close();

时间:2011-07-14 08:18:22

标签: c++ qt sqlite

我正在检查我所做的应用程序的内存使用情况。它进行了大量调用,以便在数据库中读取和写入值(SQLite 3)。我观察到以下情况:

  • QSqlQuery :: exec()使用一些KB的RAM来执行给定的查询,但是在内存超出范围后不会释放内存。

  • QSqlDatabase :: open()&如文档所示,close()不会帮助释放资源。如果有的话,close()会导致资源(至少是内存)保持“堆积”在堆/堆栈上。

例如,这是我用来访问我的数据库的典型代码段。

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();

经过实验,我发现下面的代码'陷阱'更少的内存:

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

QSqlQuery query(strQuery, db);

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

但是,仍然没有释放少量内存。还有其他人经历过这样的事吗?

我可以解释一下如何释放这段记忆吗?

P.S。同样发生在这里,一些内存永远不会释放:

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();

3 个答案:

答案 0 :(得分:3)

似乎为了释放这个内存,你必须创建QSqlQuery变量作为指针,并在关闭数据库之前删除这个指针:

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();

数据库关闭后会释放内存。

答案 1 :(得分:1)

从QSqlDatabase :: addDatabase和QSqlDatabase :: database()的文档中可以推断出存在一个管理数据库连接的全局变量。如果你查看qsqldatabase.cpp,你会发现一个QConnectionDict。

BTW:不要通过连接字符串来构造SQL查询,如果查询的某些部分有可能来自用户输入,请始终使用prepare和bindValue(SQL注入!)。

答案 2 :(得分:1)

在关闭数据库之前,必须使用QSqlQuery.finish()或QSqlQuery.clear。否则,Query对象中会遗漏剩余内存。在文档中提到Query对象可以用于多个查询。当您查询10,000条记录时,您会注意到“内存泄漏”。内存使用率急剧上升。