2009-08-14 5 views
2

Je suis en train d'exécuter un système écrit en C++ qui insère continuellement de grandes quantités de données dans ma base de données et en même temps en interrogeant la base de données pour les résultats mis à jour. Mon problème est que les threads postgres démarrés dans ce processus utilisent continuellement de plus en plus de mémoire. J'ai besoin de savoir comment corriger ce problème. Ce qui suit est un programme beaucoup plus simple qui démontre ce problème.Fuite de mémoire 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

Je pense qu'il veut dire que la consommation de mémoire Postgres.exe est en croissance, pas sa propre application. – sivabudh

+0

Je suis confronté à un problème similaire. Comme j'utilise une approche similaire (thread Reader Writer), je peux voir qu'il y a une fuite de mémoire à travers mon débogueur. Avez-vous rencontré une solution? –

Répondre

1

Vous avez peut-être besoin de fermer vos connexions d'une certaine façon?

+0

Il les ferme avec PQfinish (conn); Le problème est que ce n'est pas une exception sûre. –

+0

Les fonctions operator()() ne le ferment qu'en cas d'erreur. – erikkallen

+0

si nous fermions les connexions pour chaque fois que nous faisons un select ou un insert, le problème de fuite de mémoire dans postgres.exe disparaîtrait. Cependant, dans une application en temps réel, la latence engendrée par la réouverture d'une connexion pour chaque requête est trop importante pour que la connexion reste ouverte. – sivabudh