Destruir Lista de Classes na Memória

10/12/2009

4

Pessoal, bom dia, estou criando uma lista de Classes na Memória, quando execute o

Destructor Destroy, o sistema não destroi a lista ou seja cada vez o tamanho do sistema infla mais na memória até o ponto de causar um "Out Of Memory".

Obs: São classes criadas por mim mesmo herdadas de TObject

Aguardo alguma ajuda.

Desde já agradeço
Responder

Posts

10/12/2009

Fabiano Góes

bom dia amigo,

não entendi bem o seu problema, o certo seria você postar seu código, mais vou tentar dar uma dica:

quando você está instanciando suas classes você tem usado try - finally pra garantir a liberação da memória:







Responder

10/12/2009

Silvio Caetano

 Sugiro que você utilize:    FreeAndNil(SuaClasse);    Esse método ganrante que seu objeto será totalmente destruido.
Responder
Bom, vou explicar melhor o que esta ocorrendo:

Minhas classes são feitas da seguinte forma:

MinhaClasse heradada de ClasseBaseDeTodasAsMinhasClasses que por sua vez é herdada de TObject

Na ClasseBaseDeTodasAsMinhasClasses estão métodos de inicialização, persistencia etc...

Na MinhaClasse as vezes possui listas de outras classes que são formadas da mesma forma e etc...

Minhas duvidas são:

-Como eu devo implementa o destructor nelas para que elas sejam realmente limpas com o Free?
-Deixo somente o da TObject?
-Tem que ter um destructor por cada herança, chamando os destructors das classes herdadas?
-No caso de Classes com Listas de outras classes dentro, tenhe que chamar o destructor delas em algum lugar, para que ele seja destruido?

O caso é que acompanhando pelo proprio Gerenciador de Tarefas do Windows, minha aplicação so engorda, raros momentos ela libera alguma memória. Ja tentei observar como os proprios componentens do delphi implementam seus destrutores, mas não sei se não entendi ou realmente não deu mto efeito.

Aguardo alguma ajuda.

Desde já agradeço
Responder

11/12/2009

Wilson Junior

TMinhaClasse = class(TObject)
private
  FObjLocalMinhaClasse: TObject;
public
  destructor Destroy; override;
end;

destructor TMinhaClasse.Destroy;
begin
  FreeAndNil( FObjLocalMinhaClasse );

  inherited;
end;


Assim, você não só "mata" o seu FObjLocalMinhaClasse, como também o libera da memória, caso não fazer o FreeAndNil, o mesmo ficará em memória.

Espero ter ajudado.
Responder

11/12/2009

Marcos Iwazaki

Amigo.
  Se ver ver os codigo do TObject vai ver que o destroy dele é Virtual;

Bom seguindo este principio ja que vc herdou dele vc vai ter que implementar o seu destroy.

Parece que vc esta fazendo uma bagunça de OOP. Na verdade tem que simplificar ao máximo.

Por lembre-se que cada objeto deve ter a sua responsabilidade. A classe pai deve saber qdo deve mandar a classe filha liberar as coisas da memoria.

Acho que deveria postar alguns pedaços do codigo para facilitar, pois o problema pode estar na implementação dos objetos como tbm no seu uso.

E lembre-se objetos que não tem owner, por exemplo TList, TObject... não vão saber qdo deve ser destruidos, então vc tem a obrigação de destrui-los.

Espero ter ajudado. 
Responder
Bom dando nome aos bois e simplificando o contexto, tirando as listas da jogada;

TBaseEntity = class(TObject)
  possui 5 campos string, 2 boolean e 1 integer
o resto é procedure e function

possui 3 formas de create, em uma delas na qual eu estou usando para teste
ele somente chama um metodo virtual; abstract; na classe filha
no qual so consta passar valores para 3 dos 5 campos string da classe pai

os destructor dele estao assim

    destructor Destroy; override;
    protected
      procedure DestroyChild; virtual;
 
destructor TBaseEntity.Destroy;
begin
  DestroyChild;
  inherited Destroy;
end;

classe filha

  TProcedimento = class(TBaseEntity)
    procedure DestroyChild; override;

procedure TProcedimento.DestroyChild;
begin
//  inherited;
end;



teste:


procedure TformTeste.btnCarregarClick(Sender: TObject);
var
  i, total: Integer;
  v: array of TProcedimento;
begin
  total := 1000000;
  SetLength(v, total);
  for i := 0 to total do begin
    v[i] := TProcedimento.CreateForTeste;
  end;
//AQUI A MEMORIA CHEGA A UNS 120MB
  ShowMessage('CARREGADO');
    for i := 0 to total do begin
    v[i].Destroy;
    //JA TENTEI FreaAnNill, try finally de tudo aqui.
  end;
  ShowMessage('DESCARREGADO');
//AQUI A MEMORIA NEM COÇA 120MB
end;


Responder