Consumo de memória Delphi/Firebird
30/03/2016
0
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
Artur Barth
Posts
30/03/2016
Mateus Ribeiro
Boa sorte.
30/03/2016
Artur Barth
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...
30/03/2016
Raylan Zibel
qryEmp := tSqlQuery.Create(Self);
e...
qryEmp.Free;
30/03/2016
Artur Barth
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
....
30/03/2016
Artur Barth
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.
13/02/2019
Digifred Ltda
14/02/2019
Daniel Araújo
https://pt.stackoverflow.com/questions/305436/reduzir-consumo-mem%C3%B3ria-firebird-ao-fechar-dataset
14/02/2019
Emerson Nascimento
Veja se para o seu caso não pode ser útil trabalhar com a propriedade KeepConnection do SQLConnection.
14/02/2019
Artur Barth
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.
Clique aqui para fazer login e interagir na Comunidade :)