2011-07-14 16 views
4

私が作ったアプリケーションのメモリ使用量をチェックしています。データベースとの間で値の読み書きを行うための多数の呼び出しを行います(SQLite 3)。私は、次のことを観察しました:QSqlQueryメモリの問題。 QSqlQuery :: exec()とQSqlDatabase :: open()/ close();

  • QSqlQuery :: EXEC()は、特定のクエリを実行するためにRAMのいくつかのKBを使用しますが、それはスコープの外に出た後、メモリを解放しません。

  • 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

このメモリを解放するために、あなたはポインタとして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(); 

データベースが閉じた後、メモリはその後解放されます。

+0

ここでは、メモリはクエリで削除されません。問題はメモリリークと同じです。 –

1

QSqlDatabase :: addDatabaseとQSqlDatabaseのドキュメントから::データベース()1は、データベース接続を管理し、グローバル変数があることを推測することができます。 qsqldatabase.cppを調べると、QConnectionDictが見つかります。

BTW:文字列を連結してSQLクエリを構成しないでください。クエリの一部がユーザー入力から来る可能性がある場合は、常にprepareとbindValue(SQL注入)を使用してください。

1

データベースを閉じる前に、QSqlQuery.finish()またはQSqlQuery.clearを使用する必要があります。さもなければ、残余のメモリはQueryオブジェクトに残されます。ドキュメントでは、Queryオブジェクトを複数のクエリに使用できることが記述されています。 10,000レコードを照会すると、「メモリーリーク」に気づくでしょう。メモリ使用量は大幅に増加します。

+0

QSqlQueryオブジェクトを削除してDBを閉じるためには、finish()またはclear()を "解決策"と呼んでください。私はDBをまったく閉じるつもりはなく、QSqlQueryオブジェクトを削除してもメモリは解放されませんでした。終了だけがリソースをクリアしました。そして、私は非常にfat select文を使用しているので、これは私のプログラムのメモリ使用量の半分です。 – arthur

関連する問題