Serviço do windows feito em delphi acumulando memória Ram.
Caros, bom dia.
Peço a ajuda de vcs com um problema que passo na empresa que está causando uma grande dor de cabeça.
A empresa possui um webservice q recebe uma conexão é o resultado dessa conexão é a criação de um arquivo xml.
Porém por segundo esse webservice recebe em média 5 há 10 conexões gerando assim muito arquivos xml, é esse serviço é ininterrupto.
Então criamos um serviço do windows que lê esse arquivo xml, e faz uma série de tratamentos.
Essa série de tratamentos inclui acesso a 3 bases de dados no firebird e um acesso no mysql.
A questão é a seguinte esse serviço após algum tempo começa a acumular a memória do windows causando o travamento da máquina, logo transtorno para a empresa pois o serviço não pode parar.
o arquivo possui um campo chamado id, a partir dele verifica-se se o id é valido ou não, se for válido, busca os dados ref. a esse id, com os dados resgatados, faz então uma série de verificações com os dados q vieram no arquivo xml, tenho então um banco q salva sempre a último dado enviado, logo eu consulto e verifico se aquele dado está no banco e se tiver verificado a data de envio se a do arquivo xml for maior atualizo esse banco, e depois eu armazeno esses dados em outro banco q irá armazenas todos eles porém não pode repetir, então eu preciso fazer um select e verificar se esse id e os outros dados já foram salvos se não acrescento esse arquivo nessa base.Essa base na onde se salva todos os arquivos sem duplicidade normalmente por dia são registrados 650.000 linhas.A base que possui os dados para a primeira verificação possui 5000 linhas.A base que possui somente os ultimos dados possui 3600 linhas.
Hj a estrutura é bem simples.
TsqlConnection para casa base e um TSqlquery para cada connection, e aí utiliza eles mesmos.
Porém já se foi utilizado carrega as bases menores em ClientDataset's e utiliza-los para fazer os tratamentos, o programa fica bem rápido porém a memória aumenta muito.
Já foi feito também que todos os componentes fossem criados em tempo de execução, só alguns, mas a questão do aumento da memória contínuava.
Eu gostaria de saber se alguém já passou por algo parecido, e qual foi a solução.
Peço a ajuda de vcs com um problema que passo na empresa que está causando uma grande dor de cabeça.
A empresa possui um webservice q recebe uma conexão é o resultado dessa conexão é a criação de um arquivo xml.
Porém por segundo esse webservice recebe em média 5 há 10 conexões gerando assim muito arquivos xml, é esse serviço é ininterrupto.
Então criamos um serviço do windows que lê esse arquivo xml, e faz uma série de tratamentos.
Essa série de tratamentos inclui acesso a 3 bases de dados no firebird e um acesso no mysql.
A questão é a seguinte esse serviço após algum tempo começa a acumular a memória do windows causando o travamento da máquina, logo transtorno para a empresa pois o serviço não pode parar.
o arquivo possui um campo chamado id, a partir dele verifica-se se o id é valido ou não, se for válido, busca os dados ref. a esse id, com os dados resgatados, faz então uma série de verificações com os dados q vieram no arquivo xml, tenho então um banco q salva sempre a último dado enviado, logo eu consulto e verifico se aquele dado está no banco e se tiver verificado a data de envio se a do arquivo xml for maior atualizo esse banco, e depois eu armazeno esses dados em outro banco q irá armazenas todos eles porém não pode repetir, então eu preciso fazer um select e verificar se esse id e os outros dados já foram salvos se não acrescento esse arquivo nessa base.Essa base na onde se salva todos os arquivos sem duplicidade normalmente por dia são registrados 650.000 linhas.A base que possui os dados para a primeira verificação possui 5000 linhas.A base que possui somente os ultimos dados possui 3600 linhas.
Hj a estrutura é bem simples.
TsqlConnection para casa base e um TSqlquery para cada connection, e aí utiliza eles mesmos.
Porém já se foi utilizado carrega as bases menores em ClientDataset's e utiliza-los para fazer os tratamentos, o programa fica bem rápido porém a memória aumenta muito.
Já foi feito também que todos os componentes fossem criados em tempo de execução, só alguns, mas a questão do aumento da memória contínuava.
Eu gostaria de saber se alguém já passou por algo parecido, e qual foi a solução.
Skytrack Ltda
Curtidas 0
Respostas
Wilson Junior
16/08/2010
Tente criar índices na sua tabela, para executar os SQLs mais rápido, pode ser que já lhe ajuda um pouco.
Espero ter colaborado.
Espero ter colaborado.
GOSTEI 0
Skytrack Ltda
16/08/2010
Tente criar índices na sua tabela, para executar os SQLs mais rápido, pode ser que já lhe ajuda um pouco.
Espero ter colaborado.
Espero ter colaborado.
Obrigado por responder, as tabelas já possuem índices.
GOSTEI 0
Emerson Nascimento
16/08/2010
abra as tabelas somente enquanto precisar delas.
talvez elas estejam abertas constantemente e com o acúmulo de informações, obviamente haverá mais uso de RAM.
para evitar o acúmulo,
- abra o XML,
- leia o que for preciso,
- compare com a tabela do banco de dados (usando queries para buscar o menor número de registros possível),
0 faça o que tiver que fazer (inserir registros, atualizar) e depois
- libere o XML da memória e feche a tabela.
talvez elas estejam abertas constantemente e com o acúmulo de informações, obviamente haverá mais uso de RAM.
para evitar o acúmulo,
- abra o XML,
- leia o que for preciso,
- compare com a tabela do banco de dados (usando queries para buscar o menor número de registros possível),
0 faça o que tiver que fazer (inserir registros, atualizar) e depois
- libere o XML da memória e feche a tabela.
GOSTEI 0
Skytrack Ltda
16/08/2010
- abra o XML,
- leia o que for preciso,
- compare com a tabela do banco de dados (usando queries para buscar o menor número de registros possível),
0 faça o que tiver que fazer (inserir registros, atualizar) e depois
- libere o XML da memória e feche a tabela.
muito obrigado por ter respondido, porém isso também já é feito .
GOSTEI 0
Marco Salles
16/08/2010
Ha possibilidade de vereificar se ha Vazamento de memoria
Usar o FastMM ou para as versões mais novas do delphi
no dpr colocar
Acontece muitas vezes , vejo constantemente em Artigos e Autores conceituados de usar function
Retornando Objetos em lugar de procedures com passagem de parâmetro. A Cada execução da
function o Objeto é criado dentro da função ( que pode ser um servidor) e não destruido
Existe a possibilidade de Acumulo de Memoria ( Memory Leak ) nestes casos , o que pode ocasionar
o erro descrito por vc
{$R *.res}
begin
ReportMemoryLeaksOnShutdown:=True;
Application.Initialize;
....
GOSTEI 0
Marcos Iwazaki
16/08/2010
Amigo....
Pelo que vc reportou... pode ser problema em qualquer parte do sistemaXDtanto no banco, no acesso ao ao xml, nos sql
Primeiro acho q vc deve tentar descobrir onde esta o problema, se é no acesso de algum dos bancos, se é na execução de sql em algum dos bancos, se é qdo vai abrir um xml grande.
Uns exemplos de soluções se o problema for no Mysql, e tiver usando D2007 e dbexpress por exemplo: - tive problema que usando o driver nativo do delphi para acessar o mysql fazendo testes na minha propria maquina e somente eu fazendo os teste.... verifiquei que depois que eu fazia varias operações, o mysql tinha aberto mais de 15 conexões no banco, e ia aumentando a qtd e pior ainda.... isso as vezes passava o limite do banco (e so tinha eu conectado no banco), e ainda o banco começava a ficar lento. Como solução eu instalei o driver da corelab, isso ae resolveu este problema
- Lentidão do banco Firebird, fazer um backup e restore e analisar os indicies para ver se estão corretos.
- xml mto grande, bom ja trabalhei em um projeto onde tinha que carregar varios registros do banco em arquivo texto (sped fiscal), e qdo o arquivo ficava grande tudo ficava mais lento, pois é tudo carregado em memória. E se eu trabalhasse com arquivo direto no hd daria mto acesso de I/O e deixaria lento... então eu separei em blocos grandes o meu aquivo, e salvava no hd e começava outro arquivo, qdo terminava este eu salvava junto aquele arquivo que salvei antes.... assim não sobrecarregava a memória.
Mas a minha sugestão é Divide and conquer (dividir e conquistar), tente separar bem os fatos para saber onde realmente esta vindo o problema dae é mais facil identificá-lo.
espero ter ajudado.flw.
Pelo que vc reportou... pode ser problema em qualquer parte do sistemaXDtanto no banco, no acesso ao ao xml, nos sql
Primeiro acho q vc deve tentar descobrir onde esta o problema, se é no acesso de algum dos bancos, se é na execução de sql em algum dos bancos, se é qdo vai abrir um xml grande.
Uns exemplos de soluções se o problema for no Mysql, e tiver usando D2007 e dbexpress por exemplo: - tive problema que usando o driver nativo do delphi para acessar o mysql fazendo testes na minha propria maquina e somente eu fazendo os teste.... verifiquei que depois que eu fazia varias operações, o mysql tinha aberto mais de 15 conexões no banco, e ia aumentando a qtd e pior ainda.... isso as vezes passava o limite do banco (e so tinha eu conectado no banco), e ainda o banco começava a ficar lento. Como solução eu instalei o driver da corelab, isso ae resolveu este problema
- Lentidão do banco Firebird, fazer um backup e restore e analisar os indicies para ver se estão corretos.
- xml mto grande, bom ja trabalhei em um projeto onde tinha que carregar varios registros do banco em arquivo texto (sped fiscal), e qdo o arquivo ficava grande tudo ficava mais lento, pois é tudo carregado em memória. E se eu trabalhasse com arquivo direto no hd daria mto acesso de I/O e deixaria lento... então eu separei em blocos grandes o meu aquivo, e salvava no hd e começava outro arquivo, qdo terminava este eu salvava junto aquele arquivo que salvei antes.... assim não sobrecarregava a memória.
Mas a minha sugestão é Divide and conquer (dividir e conquistar), tente separar bem os fatos para saber onde realmente esta vindo o problema dae é mais facil identificá-lo.
espero ter ajudado.flw.
GOSTEI 0
Carlos Mazzi
16/08/2010
Se cria um objeto do tipo TDataSet, tente criar e destruir, isso faz com que o uso da memoria seja usado de forma mais transparente.
Ja tive problemas assim e soh resolveu dessa forma.
Os objetos de dataware, ficavam dando erros de memoria, por que eram muitos processos (recorrentes, concorrentes)... resolvi criando-os em tempo de execucao e destruindo ao final do processo (de cada processo)
assim resolveu, tenta ver se eh o seu caso... qq coisa posta ai.
Abracos++
GOSTEI 0
Skytrack Ltda
16/08/2010
Ha possibilidade de vereificar se ha Vazamento de memoria
Usar o FastMM ou para as versões mais novas do delphi
no dpr colocar
Já utilizei também o FastMM e até já baixei uma dll melhorada do midas.dll, pois essa é a responsável também pelo gerenciamento de memória dos ClientDataSet e essa biblioteca nativa do delphi não faz muito bem essa tarefa.
Usar o FastMM ou para as versões mais novas do delphi
no dpr colocar
{$R *.res}
begin
ReportMemoryLeaksOnShutdown:=True;
Application.Initialize;
....
Já utilizei também o FastMM e até já baixei uma dll melhorada do midas.dll, pois essa é a responsável também pelo gerenciamento de memória dos ClientDataSet e essa biblioteca nativa do delphi não faz muito bem essa tarefa.
GOSTEI 0