2009-08-14 22 views
2

Ich führe ein System in C++ geschrieben, das kontinuierlich große Datenmengen in meine Datenbank einfügt und gleichzeitig die Datenbank nach aktualisierten Ergebnissen abfragt. Mein Problem ist, dass die Postgres-Threads, die in diesem Prozess gestartet werden, immer mehr Speicher verwenden. Ich muss wissen, wie ich dieses Problem beheben kann. Das folgende ist ein viel einfacheres Programm, das dieses Problem veranschaulicht.PosgresSQL Speicherleck

#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

Ich glaube, er bedeutet, dass der postgres.exe Speicherverbrauch wächst, nicht seine eigene Anwendung. – sivabudh

+0

Ich stehe vor einem ähnlichen Problem. Wenn ich einen ähnlichen Ansatz (Reader Writer-Thread) verwende, kann ich sehen, dass ein Speicherleck durch meinen Debugger passiert. Sind Sie auf eine Lösung gestoßen? –

Antwort

1

Vielleicht brauchen Sie Ihre Verbindungen in irgendeiner Weise zu schließen?

+0

Er schließt sie mit PQfinish (conn); Das Problem ist, dass dies nicht ausnahmslos sicher ist. –

+0

Der Operator()() schließt nur im Fehlerfall. – erikkallen

+0

Wenn wir die Verbindungen für jedes Mal schließen, wenn wir eine Auswahl oder Einfügung vornehmen, wird das Problem des Speicherlecks in postgres.exe beseitigt. In einer Echtzeitanwendung ist jedoch die Latenz, die durch das erneute Öffnen einer Verbindung für jede Abfrage entsteht, zu groß, als dass die Verbindung geöffnet bleiben müsste. – sivabudh