Destruir instancia da memoria
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...
helllppppp.....
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
Curtidas 0
Respostas
Massuda
21/07/2006
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; ...
GOSTEI 0
Marco Salles
21/07/2006
[b:0f2429c6ed]Citação de massuda :[/b:0f2429c6ed]
[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]
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]
GOSTEI 0
Massuda
21/07/2006
Marco, sua explicação está perfeita.
GOSTEI 0
Sremulador
21/07/2006
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...
GOSTEI 0
Bruno Belchior
21/07/2006
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.
GOSTEI 0
Marco Salles
21/07/2006
citação de marco salles
... [/quote:41443584b8]
em outras palavras:
citação de Bruno Belchior
[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.
GOSTEI 0
Sremulador
21/07/2006
hunnnn........., blz...
GOSTEI 0
Raserafim
21/07/2006
então não é preciso destruir nada? tudo o que foi criado dentro do procedimento vai ser destruido por ele?
GOSTEI 0
Michael
21/07/2006
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:
E, no local da chamada a esta procedure:
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.
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
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
GOSTEI 0
Siam
21/07/2006
Pelo que ví, a função original RerImage deveria retornar um TBitmap mas não está retornando nada.
GOSTEI 0
Marco Salles
21/07/2006
[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]
[b:a162055b0c]Falou Tudo...[/b:a162055b0c]
GOSTEI 0
Siam
21/07/2006
[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ê ?
GOSTEI 0
Marco Salles
21/07/2006
Qeum fez a colocação foi o [b:b2c47def40]Michael[/b:b2c47def40]
:arrow:
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]
[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]
GOSTEI 0
Siam
21/07/2006
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.
Gostaria que fosse fundamentada essa teoria pq até então acho que vai da maneira de cada um programar.
GOSTEI 0
Marco Salles
21/07/2006
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]
GOSTEI 0
Siam
21/07/2006
Se voce usa funçoes e destroi o objeto referenciado no final da função no meu entendimento isto não esta correto...
Mas quando se cria uma função para retornar um objeto, pq alguém destruiria esse objeto no final da função ? Isso pra mim não faz sentido.Agora, é claro que se vc cria uma função retornando um objeto e esse objeto for criado sem o Owner, vc tem que saber que deve liberá-lo após sua utilização.
Ainda não estou convencido que é melhor utilizar procedures ao invés de funções.
GOSTEI 0
Michael
21/07/2006
[quote:66d27ead2f=´marcos salles´]1)
quando se usa funçoes , 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 [b:66d27ead2f]micheus[/b:66d27ead2f] em seu paragrafo sobre o assunto[/quote:66d27ead2f]
Micheus não, [b:66d27ead2f]Michael[/b:66d27ead2f]. ;-)
Isso não é uma teoria, mas uma boa prática de programação. Siga-a se achar conveniente. Apenas por curiosidade, segue a tradução do primeiro tópico sobre gerenciamento de exceções do [url=http://www.econos.de/delphi/cs.html]Delphi 4 Developer´s Guide Coding Standards Document[/url]:
[quote:66d27ead2f=´Xavier Pacheco´]Uso de try..finally
Sempre que possível, cada alocação de memória deve ser coincidir com uma construção try...finally.
SomeClass2 := TSomeClass.Create;
try
{ do some code }
finally
SomeClass2.Free;
end;[/quote:66d27ead2f]
Como é sabido, isso não é possível de ser feito dentro de uma função que retorne um objeto.
Como já dito acima, quando se cria um objeto, a estrutura de código que deve ser seguida é:
A única exceção é se o objeto sendo criado for um componente [u:66d27ead2f]E[/u:66d27ead2f] possuam um [b:66d27ead2f]Owner[/b:66d27ead2f]. Então vc a função vai retorna apenas o ponteiro para a instância, mas quem vai destruí-la vai ser outro componente.
Se vc tem uma função que cria um objeto e não o destrói ao final do seu uso, então a estrutura acima está sendo quebrada e isso pode levar, como eu já comentei,a memory leaks na aplicação.
Apenas componentes têm Owner. Objetos não.
Quando se trabalha em equipe, um outro programador que usar uma função assim pode não saber como ela foi criada, e portanto não saberá se destrói ou não o objeto sendo retornado.
A VCL é um bom exemplo disso. A maioria das funções não retornam objetos. E nas que fazem a instância retornada é gerenciada internamente pela classe (neste caso a função seria um método), que a libera da memória no momento certo, sem repassar esta responsabilidade para o programador.
[]´s
quando se usa funçoes , 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 [b:66d27ead2f]micheus[/b:66d27ead2f] em seu paragrafo sobre o assunto[/quote:66d27ead2f]
Micheus não, [b:66d27ead2f]Michael[/b:66d27ead2f]. ;-)
Gostaria que fosse fundamentada essa teoria pq até então acho que vai da maneira de cada um programar.
Isso não é uma teoria, mas uma boa prática de programação. Siga-a se achar conveniente. Apenas por curiosidade, segue a tradução do primeiro tópico sobre gerenciamento de exceções do [url=http://www.econos.de/delphi/cs.html]Delphi 4 Developer´s Guide Coding Standards Document[/url]:
[quote:66d27ead2f=´Xavier Pacheco´]Uso de try..finally
Sempre que possível, cada alocação de memória deve ser coincidir com uma construção try...finally.
SomeClass2 := TSomeClass.Create;
try
{ do some code }
finally
SomeClass2.Free;
end;[/quote:66d27ead2f]
Como é sabido, isso não é possível de ser feito dentro de uma função que retorne um objeto.
Mas quando se cria uma função para retornar um objeto, pq alguém destruiria esse objeto no final da função ? Isso pra mim não faz sentido.
Como já dito acima, quando se cria um objeto, a estrutura de código que deve ser seguida é:
Objeto := TObjeto.Create; try // Alguma coisa é feita com Objeto finally Objeto.Free; end;
A única exceção é se o objeto sendo criado for um componente [u:66d27ead2f]E[/u:66d27ead2f] possuam um [b:66d27ead2f]Owner[/b:66d27ead2f]. Então vc a função vai retorna apenas o ponteiro para a instância, mas quem vai destruí-la vai ser outro componente.
Se vc tem uma função que cria um objeto e não o destrói ao final do seu uso, então a estrutura acima está sendo quebrada e isso pode levar, como eu já comentei,a memory leaks na aplicação.
Agora, é claro que se vc cria uma função retornando um objeto e esse objeto for criado sem o Owner...
Apenas componentes têm Owner. Objetos não.
...vc tem que saber que deve liberá-lo após sua utilização
Quando se trabalha em equipe, um outro programador que usar uma função assim pode não saber como ela foi criada, e portanto não saberá se destrói ou não o objeto sendo retornado.
A VCL é um bom exemplo disso. A maioria das funções não retornam objetos. E nas que fazem a instância retornada é gerenciada internamente pela classe (neste caso a função seria um método), que a libera da memória no momento certo, sem repassar esta responsabilidade para o programador.
[]´s
GOSTEI 0
Siam
21/07/2006
Como disse, vai da maneira de cada um programar. De um modo geral, objetos criados devem ser liberados sejam em procedures ou funções.
GOSTEI 0