Fórum Destruir instancia da memoria #325784

21/07/2006

0

Amigo se puderem ajudar eu agradeço, já fiz de tudo, mas nada, o que esta contecendo e que quanto mais eu executo a função abaixo mais memoria ele consome, gereando um grande erro de memory leak, será que alguem pode me ajudar...


Function RerImagem: Tbitmap;
Var
Tb: TBitmap;
begin
  Tb:= TBitmap.Create;
       try
       Tb.Width := 700;
       Tb.Height:= 500;
       ct.BufferedDisplay:=False;
       ct.Draw(Tb.Canvas,Rect(0, 0, 700, 500));
       ct.BufferedDisplay:=True;
       Result:= Tb;
       finally
//       FreeAndNil(Tb); se habilitar aqui não retorna a imagem
       end;
end;


helllppppp.....


Sremulador

Sremulador

Responder

Posts

21/07/2006

Massuda

Do jeito que sua função foi escrita, você deve destruir o bitmap criado pela função [b:4763525521]depois[/b:4763525521] de utilizar o bitmap, por exemplo...
var
  Bitmap: TBitmap;
...
  Bitmap := RerImagem;
  // faz alguma coisa com Bitmap
  Bitmap.Free;
...



Responder

Gostei + 0

21/07/2006

Marco Salles

[b:0f2429c6ed]Citação de massuda :[/b:0f2429c6ed]
Do jeito que sua função foi escrita, você deve destruir o bitmap criado pela função depois de utilizar o bitmap, por exemplo...Código: var Bitmap: TBitmap; ... Bitmap := RerImagem; // faz alguma coisa com Bitmap Bitmap.Free; ...



[b:0f2429c6ed]´Neste caso, sremulador , voce esta criando uma função que retornará uma nova instância de TBitmap . Portanto não é correto destruir o objeto referenciado por Tb no final da função, porque assim destruirá o próprio objeto que deveria ser retornado, devolvendo um ponteiro inválido que pode causar uma AccessViolation na primeira referência ao objeto na memória. entre outros erros´[/b:0f2429c6ed]


Responder

Gostei + 0

21/07/2006

Massuda

Marco, sua explicação está perfeita.


Responder

Gostei + 0

22/07/2006

Sremulador

Neste caso, sremulador , voce esta criando uma função que retornará uma nova instância de TBitmap . Portanto não é correto destruir o objeto referenciado por Tb no final da função, porque assim destruirá o próprio objeto que deveria ser retornado, devolvendo um ponteiro inválido que pode causar uma AccessViolation na primeira referência ao objeto na memória. entre outros erros´


Concordo plenamente, mas como resolver esta broncad...


Responder

Gostei + 0

22/07/2006

Bruno Belchior

Ai é como o Massuda falou, o método que chamou essa função, fica com a responsabilidade de destruir esse objeto depois que seu uso não é mais necessário.


Responder

Gostei + 0

22/07/2006

Marco Salles

citação de marco salles
[quote:41443584b8]Citação de massuda : Citação: Do jeito que sua função foi escrita, [b:41443584b8]você deve destruir o bitmap criado pela função depois de utilizar o bitmap[/b:41443584b8], por exemplo...Código: var Bitmap: TBitmap; ... Bitmap := RerImagem; // faz alguma coisa com Bitmap [b:41443584b8]Bitmap.Free;[/b:41443584b8]

... [/quote:41443584b8]

em outras palavras:

citação de Bruno Belchior
Ai é como o Massuda falou, o método que chamou essa função, fica com a responsabilidade de destruir esse objeto depois que seu uso não é mais necessário.



Responder

Gostei + 0

22/07/2006

Sremulador

hunnnn........., blz...


Responder

Gostei + 0

05/08/2006

Raserafim

então não é preciso destruir nada? tudo o que foi criado dentro do procedimento vai ser destruido por ele?


Responder

Gostei + 0

06/08/2006

Michael

Quando se cria um procedimento que deve devolver a instância de uma classe, é recomendado utilizar procedures ao invés de funções. A razão disso é justamente explicitar quem será o responsável por liberar a memória alocada, no momento oportuno. O código do colega [b:814d170aca]sremulador [/b:814d170aca]poderia ser re-escrito para:

procedure RerImagem(var Imagem: TBitmap);
begin
   Imagem.Width := 700;
   Imagem.Height:= 500;
   ct.BufferedDisplay:=False;
   ct.Draw(Imagem.Canvas,Rect(0, 0, 700, 500));
   ct.BufferedDisplay:=True;
end;


E, no local da chamada a esta procedure:

var
  Imagem: TBitmap;
begin
  Imagem := TBitmap.Create;
  try
    RetImagem(Imagem);
    // Faz alguma coisa com Imagem
  finally
    Imagem.Free;
  end;
end;


Via de regra quem cria um objeto deve destruí-lo - excetuando-se componentes, que podem ter um [b:814d170aca]Owner [/b:814d170aca]para fazer isso. Se uma função retorna uma instância de uma classe, então esta responsabilidade está sendo repassada para o seu chamador, e isso muitas vezes não fica claro, o que pode levar a memory leaks na aplicação.

então não é preciso destruir nada? tudo o que foi criado dentro do procedimento vai ser destruido por ele?

Negativo. No Delphi a única forma de se ´automatizar´ a desalocação de memória de objetos é utilizando-se o mecanismo de Owner, que funciona apenas com componentes. Ou através de [b:814d170aca]interfaces[/b:814d170aca], que possuem [b:814d170aca]Reference Count[/b:814d170aca]. No mais é o programador quem deve se preocupar em liberar a memória utilizada.
Em ambientes gerenciados, como o .NET e Java, a desalocação de memória é feita pela própria plataforma, através do [b:814d170aca]Garbage Collecto[/b:814d170aca]r. Desta forma não é necessário explicitamente destruir objetos, pois isso será feito automaticamente assim que eles perderem referência (RefCount = 0).

Para quem ainda tem alguma dúvida sobre criação e destruição de objetos e componentes em run-time, eu sugiro a leituro do meu artigo sobre o assunto, publicado na edição 72 da revista ClubeDelphi.

[]´s


Responder

Gostei + 0

07/08/2006

Siam

Pelo que ví, a função original RerImage deveria retornar um TBitmap mas não está retornando nada.


Responder

Gostei + 0

07/08/2006

Marco Salles

[b:a162055b0c]Quando se cria um procedimento que deve devolver a instância de uma classe, é recomendado utilizar procedures ao invés de funções. [/b:a162055b0c]

[b:a162055b0c]Falou Tudo...[/b:a162055b0c]


Responder

Gostei + 0

07/08/2006

Siam

[quote:6c2f900232=´Marco Salles´]Quando se cria um procedimento que deve devolver a instância de uma classe, é recomendado utilizar procedures ao invés de funções.[/quote:6c2f900232]Porquê ?


Responder

Gostei + 0

07/08/2006

Marco Salles

Qeum fez a colocação foi o [b:b2c47def40]Michael[/b:b2c47def40]

[b:b2c47def40]Michael[/b:b2c47def40] escreveu: Quando se cria um procedimento que deve devolver a instância de uma classe, é recomendado utilizar procedures ao invés de funções. Porquê ?


:arrow:
A razão disso é justamente explicitar quem será o responsável por liberar a memória alocada, no momento oportuno.


Olha o parametro [b:b2c47def40]Var[/b:b2c47def40] no esboço da procedure

[b:b2c47def40]procedure RerImagem(var Imagem: TBitmap); [/b:b2c47def40]

ao inves disso:

[b:b2c47def40]Function RerImagem: Tbitmap; [/b:b2c47def40]


Responder

Gostei + 0

07/08/2006

Siam

Tenho várias funções que retornam objetos e nunca tive problemas.
Gostaria que fosse fundamentada essa teoria pq até então acho que vai da maneira de cada um programar.


Responder

Gostei + 0

07/08/2006

Marco Salles

Tenho várias funções que retornam objetos e nunca tive problemas. Gostaria que fosse fundamentada essa teoria pq até então acho que vai da maneira de cada um programar.


Se voce usa funçoes e destroi o objeto referenciado no final da função no meu entendimento isto não esta correto...

Se o sremulador , não executasse seguidas veses o mesmo codigo , não iria perceber nenhuma anormalidade , passando por despercebido , algo conceitualmente errado.

Foi dado aqui duas saídas para o problema.. Uma usando função

1)
quando se usa [b:d453a7f944]funçoes[/b:d453a7f944] , voce deve tomar o cuidado de não destruir o objeto no Final da função... Então quem deve destruir o Objeto é o Chamador. Porem , isto pode não ficar claro , com anota o micheus em seu paragrafo sobre o assunto

então esta responsabilidade está sendo repassada para o seu chamador, e isso muitas vezes não fica claro, o que pode levar a memory leaks na aplicação.


2)
Agora usando [b:d453a7f944]procedures[/b:d453a7f944] o codigo fica mais limpo pois quem cria um objeto deve destruí-lo....E na chamada voce deve passar usando o parametro [b:d453a7f944]Var[/b:d453a7f944]


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar