Ir para conteúdo
  • Cadastre-se

Balança SM100 performance surpreendente

Tecnologia Japonesa   Teclado e Visor resistentes a água
Consumo inteligente de etiquetas   Baixo custo de manutenção
Comunicação Ethernet e WIFI independentes

Comprar

Impressora de Etiquetas ELGIN - L42 PRO

Protocolos PPLA, PPLB, ZPL, EPL (automático)
Porta USB padrão Opcionais: Ethernet, Serial, Paralela
Sensor de Etiquetas Móvel Garantia de 18 meses

Comprar

Compusofts

RESPONDIDO Erro de Out Of Memory / Espaço insuficiente para executar o comando

Recommended Posts

Boa tarde, gostaria de saber se alguém já enfrentou esse tipo de situação. Minha aplicação possui várias threads que rodam simultâneas para atender as regras de negocio do cliente, crio a grande maioria dos componentes do projeto (Querys, conexões com o banco e DataTables) dinamicamente, ou seja, crio, utilizo e dou FreeAndNil. Utilizo o Delphi Tokyo com Firedac. Após um certo tempo rodando a aplicação  cerca de 72 horas seguidas o aplicativo começa a dar erro de Out Of Memory no momento de criar novos componentes, querys por exemplo. Gostaria de saber:

O comando FreeAndNil é a melhor solução para limpar da memoria os componentes criados ?

Existe algum limite na criação de componentes, por exemplo, uma aplicação suporta criar até X componentes simultâneos  somente?

Existe algum limite para criação de threads simultâneas?

Existe alguma maneira de saber quantos componentes ou threads a aplicação tem criada  (em modo debug)?

Obs: fazendo uns testes criei uma função que cria threads simultâneas para fazer um simples select no banco, quando eu mando criar mais de 1400 threads aplicação retorna um erro de espeço insuficiente para executar o comando, sendo que o aplicativo não está consumindo muita memoria ram e o computador tem memoria livre suficiente (90% livre)

Outro detalhe que não sei se influencia é que meu ambiente é 32 bits.

Nas minhas pesquisas encontrei pessoas falando que não posso criar e destruir muitos componentes isso tem algum fundamento?

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pela descrição, parece ser Memory Leak...

Pode até mesmo ser causado por alguma outra biblioteca ou componente que você usa em seus projetos...

No Lazarus/FPC usamos o HeapTrace para detectar onde está ocorrendo o vazamento.. (qual rotina criou algum objeto que não foi liberado)

No Delphi deve haver boas ferramentas para detectar isso... Veja esse post:

https://stackoverflow.com/questions/416046/what-is-the-best-tool-to-detect-memory-leaks-in-delphi

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
22 minutos atrás, Compusofts disse:

quando eu mando criar mais de 1400 threads aplicação

Um mil e quatrocentas ao mesmo tempo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim 1400, mais isso é um ambiente de testes não é a realidade é que dessa forma consigo simular o erro mais rapidamente. Se eu simular com a ambiente real demora dias para acontecer o problema.

Compartilhar este post


Link para o post
Compartilhar em outros sites
5 horas atrás, Compusofts disse:

Sim 1400, mais isso é um ambiente de testes não é a realidade

Ahh sim. Mas você deve saber que executar um número de threads maiores que o número de núcleos do processador (virtuais ou não) ao mesmo tempo não causa nenhuma melhora do desempenho, pelo contrário. Isso pode causar lentidão e até mesmo escassez de recursos, o que pode gerar um erro "Out of memory". Digo isso principalmente porque você fez essa pergunta:

20 horas atrás, Compusofts disse:

Existe algum limite para criação de threads simultâneas? 

Não existe um limite inerente no Windows. Mas você deve levar em conta a quantidade de memória e outros recursos (como "address space") que uma thread consome. Por isso você notou o seguinte:

20 horas atrás, Compusofts disse:

Obs: fazendo uns testes criei uma função que cria threads simultâneas para fazer um simples select no banco, quando eu mando criar mais de 1400 threads aplicação retorna um erro de espeço insuficiente para executar o comando, sendo que o aplicativo não está consumindo muita memoria ram e o computador tem memoria livre suficiente (90% livre) 

A pergunta certa a ser feita nesse caso não é "quantas threads você pode criar?" e sim, "Por que você quer criar tantas threads a ponto de isso ser um problema?".

Se você tem realmente essa necessidade, talvez seja melhor você criar um sistema de thread pool /thread queue/thread worker. Assim você limita o número de threads a serem executadas ao mesmo tempo, mas permite criar um número praticamente ilimitado de threads.

EDIT: Quero dizer, limita o número de threads criadas e executadas, mas permite um número praticamente ilimitado de tarefas a serem executadas.

Se quiser ler mais eu recomendo esse artigo que fala especificamente sobre essa pergunta: O Windows tem um limite de 2000 threads por processo? (em Inglês)

Agora vou tentar responder as outras perguntas.

20 horas atrás, Compusofts disse:

O comando FreeAndNil é a melhor solução para limpar da memoria os componentes criados ?

Não é possível responder essa pergunta de modo correto sem ver o código. Mas entenda que "FreeAndNil(Objeto)" simplesmente não é melhor do que "Objeto.Free".

Se você usa FreeAndNil no seu código sem entender o motivo pode ser que isso esteja escondendo alguns problemas futuros.

Tivemos um tópico sobre o assunto aqui no fórum com boas explicações. Sugiro a leitura dele:

Há muitos artigos sobre esse assunto também na internet. Recomendo estudar os seguintes:

http://tech.turbu-rpg.com/106/delphi-memory-management-made-simple

https://stackoverflow.com/q/3159376/460775

20 horas atrás, Compusofts disse:

Existe algum limite na criação de componentes, por exemplo, uma aplicação suporta criar até X componentes simultâneos  somente?

Essa pergunta tem basicamente a mesma resposta da anterior: "Por que você quer criar tantos componentes simultâneos a ponto de isso ser um problema?".

Pode até ser que isso não seja o seu real problema.

20 horas atrás, Compusofts disse:

Nas minhas pesquisas encontrei pessoas falando que não posso criar e destruir muitos componentes isso tem algum fundamento?

Não tem. Quem disse isso provavelmente repetiu o que já ouviu de outros ou não entende o real processo.

Contudo o que precisa acontecer é você criar e destruir completamente os componentes. Se isso não acontecer, haverá o que o Daniel mencionou acima: "memory leaks".

No Delphi, uma boa ferramenta gratuita pra detectar "vazamentos de memória" ou Memory Leaks é o fastMM. Ele já vem embutido desde o Delphi 2007.

Mas o seu verdadeiro poder está no modo FullDebugMode que só é conseguido com a versão completa disponível do GitHub. Experimente verificar seu projeto usando o FastMM.

Talvez queira estudar esse artigo e os que ele menciona:

https://wiert.me/2009/07/29/delphi-fastmm-using-fastmm4-for-debugging-your-memory-allocations-part-1-introduction/#comment-3407

  • Curtir 3

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito obrigado pelas respostas, vou estudar mais o assunto para solucionar o problema. Descobri que existia alguns Timers na aplicação em uma função antiga, que criava querys e não destruía elas depois de utilizar, obviamente depois de dias rodando a aplicação iria criar muitos componentes. Estou revendo todo do projeto mas muito provavelmente o problema seja esse. Acredito que até segunda consiga bater o martelo e retorno aqui como solucionei.

  • Curtir 3

Compartilhar este post


Link para o post
Compartilhar em outros sites

Só para dar um retorno,  realmente o meu problema eram os componentes que estavam sendo criados e não estavam sendo destruídos, consegui fazer a varredura do projeto revisando alguns Timer bem antigos em que não estavam sendo devidamente validados a criação/destruição dos componentes (Querys, conexões e DataTables). Deixei rodando um teste que já está a 80 horas sem apresentar falhas, foram por volta de 50 milhões de loops (Situação bem forçada e bem acima da realidade). Antes o problema ocorria antes das primeiras 24 horas por volta dos 15 milhões de loops.

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

1 hora atrás, Compusofts disse:

Só para dar um retorno,

Legal. Que bom que conseguiu resolver. Agradecemos o retorno.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora

×