Autor
Mensagem

País: Brasil
Estado: SP
Cidade: São Paulo
Mensagens: 21
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.





País: Brasil
Estado: RS
Cidade: Caxias do Sul
Mensagens: 1574
País: Brasil
Estado: SP
Cidade: São Paulo
Mensagens: 21
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.
País: Brasil
Estado: SP
Cidade: São Paulo
Mensagens: 21
Citação:
- 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.
- 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 .
Ha possibilidade de vereificar se ha Vazamento de memoria
Usar o FastMM ou para as versões mais novas do delphi
no dpr colocar
#Código
{$R *.res}
begin
ReportMemoryLeaksOnShutdown:=True;
ReportMemoryLeaksOnShutdown:=True;
Application.Initialize;
....
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
Amigo....
Pelo que vc reportou... pode ser problema em qualquer parte do sistema
XD
tanto 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.
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++
País: Brasil
Estado: SP
Cidade: São Paulo
Mensagens: 21
Citação:
Ha possibilidade de vereificar se ha Vazamento de memoria
Ha possibilidade de vereificar se ha Vazamento de memoria
Usar o FastMM ou para as versões mais novas do delphi
no dpr colocar
#Código
{$R *.res}
begin
ReportMemoryLeaksOnShutdown:=True;
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.
2013 - Todos os Direitos Reservados a web-03





