Júnior Oliveira

C Sharp; Delphi; ASP .NET; PHP; Javascript;

Garbage Collector no Delphi - Parte I

29 Dec 2010 delphi

Olá pessoal, depois de algum tempo sem postar venho com uma novidade para vocês, para alguns isto pode não ser novidade, mas tenho certeza que para outros é, pelo menos para mim foi novidade, programo em Delphi desde 2005 mais ou menos e fiquei sabendo que o Delphi tinha Garbage Collector só a dias atrás então resolvi criar uma implementação de exemplo.

Neste primeiro exemplo vou trabalhar apenas com objetos que herdam de uma classe Super Classe.

A primeira implementação é da Super Classe na qual todas as outras classes irá herdá-la, a classe é bem simples ela tem uma interface do IModel que é do mesmo tipo da IUnknown que será responsável por dizer que o objeto será liberado automaticamente e a classe TModel é quem irá herdar TInterfacedObject e a inteface IUnknown.

 1 unit Model;
 2 
 3 interface
 4 
 5 type
 6   IModel = type IUnknown;
 7 
 8   TModel = class(TInterfacedObject, IModel)
 9 
10   end;
11 
12 implementation
13 
14 end.

A segunda implementação é da Sub Classe, ela irá conter uma interface que irá conter todos os métodos necessários na classe principal e uma classe que irá herdar a Super Classe e implementar a classe que contém os métodos que serão usados na classe. Note que na frente da declaração do método Destroy existe um override pois o mesmo está declarado como virtual na classe TObject o que indica que o mesmo pode ser sobrescrito na Sub Classe.

 1 unit ModelPessoa;
 2 
 3 interface
 4 
 5 uses
 6   Dialogs, Model;
 7 
 8 type
 9   IModelPessoa = interface
10     procedure Teste();
11 
12   end;
13 
14   TModelPessoa = class(TModel, IModelPessoa)
15   public
16     { Public declarations }
17     constructor Create();
18     destructor Destroy(); override;
19     procedure Teste();
20 
21   end;
22 
23 implementation
24 
25 { TModelPessoa }
26 
27 constructor TModelPessoa.Create();
28 begin
29   ShowMessage('Create');
30 end;
31 
32 destructor TModelPessoa.Destroy();
33 begin
34   ShowMessage('Destroy');
35 
36   inherited Destroy();
37 end;
38 
39 procedure TModelPessoa.Teste();
40 begin
41   ShowMessage('Teste');
42 end;
43 
44 end.

Pronto agora é só usar mos, primeiro temos que criar uma variável do tipo da interface da Sub Classe, pois é que o coletor ficará verificando e quando a mesma sair do contexto será capturado automaticamente pelo Garbage Collector. Depois vamos instanciar esta variável pela classe concreta que implementa a nossa interface para podermos usar o objeto, note que ao instanciar o objeto irá aparecer a mensagem "Create", apos executar pelo método Teste() irá aparecer a mensagem "Teste" e por final quando terminar o método principal na qual foi declarada a variável do tipo da interface da Sub Classe irá aparecer a mensagem "Destroy" que indicará que a nossa variável foi liberada da memória pelo Garbage Collector do Delphi.

1 var
2   objPessoa: IModelPessoa;
3 
4 begin
5   objPessoa := TModelPessoa.Create();
6   objPessoa.Teste();
7 end;

Este exemplo foi feito em Delphi XE, caso queria mais uma forma de verificar se a variável foi realmente liberada da memória o Delphi XE tem a propriedade ReportMemoryLeaksOnShutdown que mostra os objetos que ainda estão na memória. Segue abaixo uma forma de usar esta propriedade.

 1 program Estudo11;
 2 
 3 uses
 4   Forms,
 5   Unit8 in 'Unit8.pas' {Form8},
 6   Model in 'Model.pas',
 7   ModelPessoa in 'ModelPessoa.pas';
 8 
 9 {$R *.res}
10 
11 begin
12   ReportMemoryLeaksOnShutdown := True;
13 
14   Application.Initialize;
15   Application.MainFormOnTaskbar := True;
16   Application.CreateForm(TForm8, Form8);
17   Application.Run;
18 end.

Espero que este exemplo seja útil a vocês de alguma forma, até a próxima.