QSqlQuery内存问题。QSqlQuery:exec()和QSqlDatabase:打开()/关闭();

时间:2021-04-30 10:49:29

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:

我正在检查我的应用程序的内存使用情况。它对数据库(SQLite 3)的读写值进行了多次调用。

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

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

  • 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.

    open()和close()不像文档建议的那样帮助免费资源。如果有的话,close()会导致资源(至少是内存)在堆/堆栈上被“捕获”。

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

3 个解决方案

#1


3  

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:

似乎为了释放这个内存,必须将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();

The memory is then released after the database closes.

在数据库关闭后,内存将被释放。

#2


1  

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.

您必须使用QSqlQuery。完成()或QSqlQuery。在关闭数据库之前清除。否则,在查询对象中保留剩余内存。文档中提到,查询对象可以用于多个查询。您将注意到“内存泄漏”。当您查询10,000条记录时。内存使用量急剧增加。

#3


1  

From the documentation of QSqlDatabase::addDatabase and QSqlDatabase::database() one can deduce that there is a global variable that manages the database connections. If you look into qsqldatabase.cpp you will find a QConnectionDict.

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

BTW: Do not construct your SQL queries by concatenating strings, always use prepare and bindValue (SQL injecttion!), if there is any chance that parts of the query come from user input.

顺便说一下,不要通过连接字符串来构造SQL查询,要经常使用准备和bindValue (SQL injecttion!),如果查询的部分来自用户输入的话。

#1


3  

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:

似乎为了释放这个内存,必须将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();

The memory is then released after the database closes.

在数据库关闭后,内存将被释放。

#2


1  

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.

您必须使用QSqlQuery。完成()或QSqlQuery。在关闭数据库之前清除。否则,在查询对象中保留剩余内存。文档中提到,查询对象可以用于多个查询。您将注意到“内存泄漏”。当您查询10,000条记录时。内存使用量急剧增加。

#3


1  

From the documentation of QSqlDatabase::addDatabase and QSqlDatabase::database() one can deduce that there is a global variable that manages the database connections. If you look into qsqldatabase.cpp you will find a QConnectionDict.

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

BTW: Do not construct your SQL queries by concatenating strings, always use prepare and bindValue (SQL injecttion!), if there is any chance that parts of the query come from user input.

顺便说一下,不要通过连接字符串来构造SQL查询,要经常使用准备和bindValue (SQL injecttion!),如果查询的部分来自用户输入的话。