Consumo de memória Delphi/Firebird
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:
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
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
Curtidas 0
Respostas
Mateus Ribeiro
30/03/2016
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.
Boa sorte.
GOSTEI 0
Artur Barth
30/03/2016
Então, já tentei isso que sugeriu. O problema persiste.
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...
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...
GOSTEI 0
Raylan Zibel
30/03/2016
Tente...
e...
qryEmp := tSqlQuery.Create(Self);
e...
qryEmp.Free;
GOSTEI 0
Artur Barth
30/03/2016
Tente...
e...
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
....
GOSTEI 0
Raylan Zibel
30/03/2016
Firebird embarcado?
GOSTEI 0
Artur Barth
30/03/2016
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.
GOSTEI 0
Digifred Ltda
30/03/2016
Artur Barth, conseguiu solucionar o problema? Estou passando por uma situação muito semelhante na questão do consumo de memória do firebrid.
GOSTEI 0
Daniel Araújo
30/03/2016
Vê se esse link te ajuda Digifred:
https://pt.stackoverflow.com/questions/305436/reduzir-consumo-mem%C3%B3ria-firebird-ao-fechar-dataset
https://pt.stackoverflow.com/questions/305436/reduzir-consumo-mem%C3%B3ria-firebird-ao-fechar-dataset
GOSTEI 0
Emerson Nascimento
30/03/2016
Veja se para o seu caso não pode ser útil trabalhar com a propriedade KeepConnection do SQLConnection.
GOSTEI 0
Artur Barth
30/03/2016
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.
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.
GOSTEI 0