Ir para conteúdo
  • Cadastre-se

dev botao

Dúvida - Free vs FreeAndNil vs DisposeOf vs Destroy/Nil


  • Este tópico foi criado há 2364 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Bom dia pessoal.

Acredito que problemas relacionados com memória sejam um dos capítulos marcantes no início da carreira de desenvolvedores. Se minha colocação estiver correta, então chegou a minha vez :D 

Estou passando por uma certa dificuldade em encontrar qual a maneira ideal para realizar a liberação de memória de nossa aplicação (objetos, componentes, etc...).

Vou primeiro para a descrição do nosso problema. Nossa aplicação atualmente não possuí vazamentos de memória (memory leaks). Este diria que foi o primeiro item do capítulo que nos deparamos e eventualmente corrigimos, com a utilização do FastMM4.

Então, o problema que estou passando é que nosso software está apresentando um crescimento constante na alocação de memória do S.O. Ou seja, ele inicia com 50mb, e ao longo do dia, após executar determinadas operações repetidamente, se encontra com 150~170~... mb. Com isso, em determinados momentos é apresentado o erro de "Out of Memory", ocasionando uma série de outros alertas ao usuário.

Num primeiro momento, chegamos a pensar que de fato ainda havia vazamentos de memória. Porém, efetuamos o encerramento natural do software em um caso onde a memória do processo chegava a 170mb, e mesmo assim, não foi apresentado nenhum vazamento de memória.

Artigos pra lá, artigos pra cá, nos deparamos com diversas colocações aconselhando única e exclusivamente o FreeAndNil. Ao mesmo tempo, outras informando que o uso do FreeAndNil deve ser evitado em 99,9% das vezes em que pretendemos utilizá-lo.

Como mencionei inicialmente, acredito que esta seja uma dúvida muito pertinente para a grande maioria dos desenvolvedores iniciantes (ou não), não sabendo qual a maneira mais correta e adequada para efetuar a liberação de objetos.

Gostaria que cada um relatasse vivências e dores que já teve em situações desse tipo, pois acredito que apenas uma descrição bem colocada, madura e real seja o suficiente para que cada desenvolvedor possa compreender o real significado de quando usar ou não determinada chamada.

Link para o comentário
Compartilhar em outros sites

  • Moderadores

Não existe diferença na liberação da memória em usar Objeto.Free ou FreeAndNil(Objeto).

A única diferença é que o FreeAndNil atribui nil à variável depois de liberar a memória, o que é desnecessário, a não ser que você precise testar o valor da variável novamente, e se você precisa fazer isso, quer dizer que está usando variáveis globais para instanciar objetos, o que é uma prática ruim, na minha opinião.

Quanto ao consumo de memória, mesmo que você não esteja tendo vazamentos ao finalizar a aplicação, pode ser que esteja instanciando objetos e não se preocupando em liberar, deixando a aplicação cuidar disso, exemplo:

var
  obj: TMinhaClasse;
begin
  obj := TMinhaClasse.Create(Application);
end;

Esse código não vai acusar vazamento de memória, pois ao finalizar, o objeto Application que é o Owner do obj se encarrega de finalizá-lo. Mas apenas ao finalizar a aplicação.

 

  • Curtir 3
Equipe ACBr BigWings
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

 

 

Link para o comentário
Compartilhar em outros sites

Olá @BigWings.

De fato, muito ouvi falar que também não havia diferença nos métodos. Porém, sempre fiquei com dúvida devido aos artigos onde cada autor defendia seus métodos de utilização.

Sobre a utilização do Create(Owner), adotamos por não passar o owner no mesmo. Assim os leaks são identificados no mesmo instante pois não são destruídos. Não sei se é a melhor prática, mas foi o que acabamos adotando.

PS: Já vou adiantando um pouco, pois em algum momento irá surgir essa coloção: "por que não utiliza o comando milagroso que reduz memória?". Já o utilizava inicialmente. Porém, optamos por descontinuar sua utilização, visto que o mesmo pode interferir em outros processos do S.O.

Editado por felipetomm
Adição hiperlink
Link para o comentário
Compartilhar em outros sites

  • Fundadores

Veja como é implementado o método FreeAndNil no FPC

    procedure FreeAndNil(var obj);
      var
        temp: tobject;
      begin
        temp:=tobject(obj);
        pointer(obj):=nil;
        temp.free;
      end;

Ou seja, como o @BigWings, comentou... a única diferença é que Ponteiro da variável deixará de apontar para um Objeto morto... e terá o valor Nil

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

  • Consultores
6 horas atrás, felipetomm disse:

Então, o problema que estou passando é que nosso software está apresentando um crescimento constante na alocação de memória do S.O. Ou seja, ele inicia com 50mb, e ao longo do dia, após executar determinadas operações repetidamente, se encontra com 150~170~... mb. Com isso, em determinados momentos é apresentado o erro de "Out of Memory", ocasionando uma série de outros alertas ao usuário.

Num primeiro momento, chegamos a pensar que de fato ainda havia vazamentos de memória. Porém, efetuamos o encerramento natural do software em um caso onde a memória do processo chegava a 170mb, e mesmo assim, não foi apresentado nenhum vazamento de memória.

Isso é um vazamento de memória. Pode não ter gerado nenhum access violation. Pode não ter sido detectado pelo FastMM. Mas continua sendo um vazamento de memória.

O motivo mais provável de não ter sido detectado é o que o @BigWings mencionou.

5 horas atrás, felipetomm disse:

Sobre a utilização do Create(Owner), adotamos por não passar o owner no mesmo. Assim os leaks são identificados no mesmo instante pois não são destruídos. Não sei se é a melhor prática, mas foi o que acabamos adotando.

Isso talvez no seu código. Pode ser um bug em alguma biblioteca que você utiliza. Pode ser até no Delphi.

  • Curtir 1

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

4 horas atrás, Daniel Simoes disse:

Veja como é implementado o método FreeAndNil no FPC

Ou seja, como o @BigWings, comentou... a única diferença é que Ponteiro da variável deixará de apontar para um Objeto morto... e terá o valor Nil

Acho que entendi o recado.

6 horas atrás, BigWings disse:

que é desnecessário, a não ser que você precise testar o valor da variável novamente, e se você precisa fazer isso, quer dizer que está usando variáveis globais para instanciar objetos, o que é uma prática ruim, na minha opinião.

Como mencionado pelo @BigWings, acredito que precisaremos rever algumas questões para ajustar o nosso código.

21 minutos atrás, EMBarbosa disse:

Isso é um vazamento de memória. Pode não ter gerado nenhum access violation. Pode não ter sido detectado pelo FastMM. Mas continua sendo um vazamento de memória.

22 minutos atrás, EMBarbosa disse:

Pode ser um bug em alguma biblioteca que você utiliza. Pode ser até no Delphi.

@EMBarbosa, tuas colocações, em conjunto com a dos colegas, puderam esclarecer e confirmar várias questões que sempre tivemos dúvidas.

Estarei retomando as alterações no nosso projeto em busca da solução.

De momento, agradeço pela dedicação e pelo conhecimento compartilhado :D

Obrigado!

Link para o comentário
Compartilhar em outros sites

  • Consultores

Verifique qual processo do usuário faz a memória ir sempre aumentando. Daí analise o código relacionado a isso.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

21 horas atrás, Edson.pol disse:

Você emite NFe ?

Verifique se está "limpando" o componente ACBrNFe após emitir uma nota por exemplo.

ACBrNFe.NotasFiscais.Clear;

Tive um problema parececido há muito tempo por causa disto.

Procure por outros componente que tenham metódo ".Add" e veja se também se aplica.

 

[]´s

Edson

 

Boa tarde Edson.

Fiz o teste mas não houve diferença no meu caso. Vou testar com um volume maior de notas, complementando a colocação abaixo.

22 horas atrás, EMBarbosa disse:

Verifique qual processo do usuário faz a memória ir sempre aumentando. Daí analise o código relacionado a isso.

Beleza @EMBarbosa, estarei fazendo esses testes com base nisso.

Link para o comentário
Compartilhar em outros sites

  • Membros
  • Curtir 1
  • Obrigado 1
Equipe ACBr Sérgio Assunção
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

 

[email protected]

Link para o comentário
Compartilhar em outros sites

  • Este tópico foi criado há 2364 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

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
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.