Consumo de memória Delphi/Firebird

30/03/2016

14

Olá, bom dia.
Estou com um problema de consumo de memória no Firebird, utilizando uma aplicação desenvolvida em Delphi.
Hoje, o banco de dados está com 80 usuários conectados simultaneamente, muitos deles abrem o sistema pela manhã e só fecham a noite, no fim do expediente, acontece que em várias consultas SQL o Firebird aloca memória e, mesmo com FreeAndNil no TSQLQuery o Firebird não libera a memória alocada. A mesma só é liberada caso feche a conexão com o banco de dados, porém, não será possível tal ação no nosso ERP.

Exemplo:
var
   qryEmp : TSQLQuery;
   tran: TDBXTransaction;
begin
   qryEmp  := tSqlQuery.Create(Application);
   qryEmp.SQLConnection := Dtm0.cnxSolution;
   tran := dtm0.cnxSolution.BeginTransaction;
   with qryEmp do begin
       Close;
       SQL.Clear;
       SQL.Add('  MINHA CONSULTA SQL  ');
       Open;
       //CÓDIGO
   end;
   dtm0.cnxSolution.CommitFreeAndNil(tran);
   FreeAndNil(qryEmp);
end;

Toda a memória alocada pela TSQLQuery nunca será liberada, a menos que feche e abra a aplicação.
Já tentei passar Create(Nil), Create(Self), Create(Application). Tentei aplicar Destroy, Tentei fazer sem transaction... Em fim, já tentei muita coisa e a memória do FB_INNET_SERVER só é liberada se fechar a aplicação... Então, com 80 usuários utilizando o sistema e levando em consideração que algumas consultas alocam mais de 100kb de memória, no final do dia o Firebird está consumindo mais de 2GB de RAM causando lentidão no sistema.

Alguém sabe como solucionar?

Att.
Artur Barth
Responder

Posts

30/03/2016

Mateus Ribeiro

Bom dia! Talvez o FreeAndNil não esteja aplicando por que a mesma está com trafego, aí entra em uma "fila de execução". Tente um qryEmp.Close antes do comando de destruir! E mude tbm pra Create(Nil);

Boa sorte.
Responder

30/03/2016

Artur Barth

Então, já tentei isso que sugeriu. O problema persiste.

    qryEmp  := tSqlQuery.Create(Nil);
    //qryEmp  := tSqlQuery.Create(Self); Já tentei também.



   dtm0.cnxSolution.CommitFreeAndNil(tran); // Já tentei também sem transação... 
   QryEmp.Close;
   FreeAndNil(qryEmp);

   //QryEmp.Close; 
   //QryEmp.Destroy; // Não resolve.


Uma forma de solucionar foi criar uma TSQLConnection em tempo de execução, ao fazer isso e matar a connection no final ele libera memória.
Só que imagine ter que alterar um sistema com mais de 2 milhões de linhas de código e centenas de classes para que todas utilizem connections criadas em tempo de execução?... Por isso estou procurando uma solução alternativa, sem ter que altera todo o sistema...
Responder

30/03/2016

Raylan Zibel

Tente...
   qryEmp  := tSqlQuery.Create(Self);

e...
   qryEmp.Free;
Responder

30/03/2016

Artur Barth

Tente...
   qryEmp  := tSqlQuery.Create(Self);

e...
   qryEmp.Free;


Já tentei também. O problema persiste.
Antes de passar pelo bloco:
fb_inet_server = 15.180K
Depois de passar pelo bloco
fb_inet_server = 15.444K

Ao executar mais uma vez..
Antes de passar pelo bloco:
fb_inet_server = 15.444K
Depois de passar pelo bloco
fb_inet_server = 15.636K

E vai subindo... Só libera quando fecha a aplicação ou quando faz
dtm0.cnxSolution.connected := false

....
Responder

30/03/2016

Raylan Zibel

Firebird embarcado?
Responder

30/03/2016

Artur Barth

Firebird embarcado?


Não, Firebird 2.5.5 SuperClassic.

Aparentemente depois de um certo tempo o Firebird libera memória, estou então alterando o arquivo Firebird.conf para tentar reduzir este tempo.
Responder

13/02/2019

Digifred Ltda

Artur Barth, conseguiu solucionar o problema? Estou passando por uma situação muito semelhante na questão do consumo de memória do firebrid.
Responder

14/02/2019

Daniel Araújo

Vê se esse link te ajuda Digifred:
https://pt.stackoverflow.com/questions/305436/reduzir-consumo-mem%C3%B3ria-firebird-ao-fechar-dataset
Responder

Veja se para o seu caso não pode ser útil trabalhar com a propriedade KeepConnection do SQLConnection.
Responder

14/02/2019

Artur Barth

Opa.
Consegui resolver sim, realizando algumas pequenas refatorações na aplicação.
Mesmo criando transação, realizando commit e na sequencia destruindo todos os objetos envolvidos (DataSets, Queryes, Providers, Transações, etc, etc, etc) a memória não reduzia.
A partir do momento que você finaliza a conexão (Connected := False) a aplicação libera a memória do Firebird. Parece ser algo relacionado ao cache.
Além disso, sugiro dar uma olhada neste link. https://ib-aid.com/br/optimized-firebird-configuration/ e utilizar uma Firebird.conf optimizada.
Responder