2009-08-14 36 views
2

私はC++で書かれたシステムを実行しています。このシステムは大量のデータをデータベースに継続して挿入しており、同時に更新された結果をデータベースに照会しています。私の問題は、このプロセスで開始されたpostgresスレッドが、ますます多くのメモリを使い続けていることです。私はこの問題を解決する方法を知る必要があります。以下は、この問題を示すはるかに簡単なプログラムです。PosgresSQLのメモリリーク

#include <iostream> 
#include <sstream> 

#include <tbb/tbb_thread.h>//intel parallel studio class for parel 

#include "libpq-fe.h" 
#include "libpq/libpq-fs.h" 

class Inserter{ 
public: 
    void operator()(){ 
     PGconn* conn = PQconnectdb("user=postgres password=1234"); 
     int i=0; 
     while(1){ 
      std::stringstream insert; 
      insert << "INSERT INTO tmp (value) VALUES (" << i%250 << ");"; 
      PGresult* res=PQexec(conn,insert.str().c_str()); 
      if (PQresultStatus(res) == PGRES_FATAL_ERROR){ 
       std::cout << "Error in inserting data:\nError code: " << PQresStatus(PQresultStatus(res)) << "Error Message: " << PQerrorMessage(conn); 
       PQclear(res); 
       PQfinish(conn); 
       return; 
      } 
      PQclear(res); 
      i++; 
     } 
    } 

}; 
class Queryer{ 
public: 
    void operator()(){ 
     PGconn* conn = PQconnectdb("user=postgres password=1234"); 
     int j=0; 
     while (1){ 
      std::stringstream query; 
      query << "SELECT * FROM tmp WHERE id>" << j%1000 << ";"; 
      PGresult* res=PQexec(conn,query.str().c_str()); 
      if (PQresultStatus(res) == PGRES_FATAL_ERROR){ 
       std::cout << "Error in searching data:\nError code: " << PQresStatus(PQresultStatus(res)) << "Error Message: " << PQerrorMessage(conn); 
       PQclear(res); 
       PQfinish(conn); 
       return; 
      } 
      PQclear(res); 
      Sleep(10); 
      j++; 
     } 
    } 

}; 

void main(){ 
    //connect to Database 
    PGconn* conn = PQconnectdb("user=postgres password=1234"); 

    //create table 
    std::cout << "Creating table...\n"; 
    PGresult* res=PQexec(conn,"CREATE TABLE tmp (id SERIAL8 PRIMARY KEY,value INT);"); 
    if (PQresultStatus(res) == PGRES_FATAL_ERROR){ 
     std::cout << "Error in Creating table:\nError code: " << PQresStatus(PQresultStatus(res)) << "Error Message: " << PQerrorMessage(conn); 
     //PQclear(res); 
     //PQfinish(conn); 
     //return; 
    } 
    PQclear(res); 
    PQfinish(conn); 

    std::cout << "Starting table filling thread...\n"; 
    //fill table with some data 
    Inserter ins; 
    tbb::tbb_thread filling(ins); 
    Sleep(1000); 
    // searching table ... here is where the memory leak is 
    std::cout << "Starting table searching thread...\n"; 
    Queryer que; 
    tbb::tbb_thread searching(que); 

    while(true) 
    { 
     tbb::tick_count::interval_t t(1.0); 
     tbb::this_tbb_thread::sleep(t); 
    } 
} 
+0

私は彼がPostgres.exeのメモリ消費量が増えていることを彼は思います、自分のアプリケーションではないと思います。 – sivabudh

+0

私は同様の問題に直面しています。同様のアプローチ(Reader Writerスレッド)を使用しているので、デバッガからメモリリークが発生していることがわかります。あなたはどんな解決策を見つけましたか? –

答えて

1

多分あなたは何らかの方法で接続を閉じる必要がありますか?

+0

彼はPQfinish(conn)でそれらを閉じています。問題は、これが例外安全ではないということです。 –

+0

operator()()関数は、エラーが発生した場合にのみ閉じます。 – erikkallen

+0

selectまたはinsertを実行するたびに接続を終了すると、postgres.exeのメモリリークの問題が解消されます。しかし、リアルタイムアプリケーションでは、すべてのクエリの接続を再オープンする際に発生する遅延が大きすぎて、接続を開いたままにしておく必要があります。 – sivabudh