GARANTIR DESCONTO

Fórum Qual a Função do Nil? #212741

10/02/2004

0

É o seguinte...

Desde quando conheci o delphi, aprendi que a melhor maneira de se liberar um objeto da memória eh atribuindo [b:91db9be032]Nil[/b:91db9be032] ao objeto.

Já ví várias dicas do tipo ´A melhor maneira de se liberar um form da memória´, etc.... E todas elas diziam pra atribuir o [b:91db9be032]Nil[/b:91db9be032] ao form.
Form1 :nil;
Só que hoje na faculdade, meu professor diz que é o contrário!
Que [b:91db9be032]Nil[/b:91db9be032] na verdade é uma constante de endereçamento nulo, que quando atribuida a um objeto, simplesmente, aquele ponteiro que apontava pra tal alocação de memória(do objeto) é, digamos, destruído, porém o objeto alocado continua na memória, só que sem um ponteiro apontado-o, e só é liberada quando sua aplicação é terminada.
E quando você recria o form que você tinha atribuido o [b:91db9be032]Nil[/b:91db9be032], ele ao invés de (digamos)reapontar o ponteiro para a mesma alocação, na verdade ele cria uma nova alocação, portanto, ao invés de liberar, o [b:91db9be032]Nil[/b:91db9be032] faz é sobrecarregar a memória.

Fiquei em dúvida, por isso gostaria que alguém que soubesse pudesse esclarecer-me esta dúvida!

Grato,


Caninha51


Caninha51

Caninha51

Responder

Posts

10/02/2004

Beppe

Ninguém nunca disse isso. Ao menos eu nunca. :shock:

O que acontece é o seguinte: quando você atribui um objeto([b:ae186feaba]nil[/b:ae186feaba] não é um objeto, mas é compativel) a uma variável, esta variável passará a referenciar este novo objeto, perdendo assim a referência para objeto anterior. Se nenhuma variável referenciar aquele objeto antigo, então ele ficará inacessível e indisponível para realocação, mesmo não podendo ser mais usado. Isto se chama [i:ae186feaba]memory leak[/i:ae186feaba]. Mais cedo ou mais tarde um [i:ae186feaba]out of memory[/i:ae186feaba] acontecerá.

Também acontece de você liberar um objeto antes do indicado, isto é, você ainda ter referências para um objeto destruído. Estas referências se chamam [i:ae186feaba]dangling references[/i:ae186feaba]. Você as corta atribuindo [b:ae186feaba]nil[/b:ae186feaba] à variável, fazendo-a representar nenhum objeto.

Dangling references devem ser evitadas a todo custo. Já as memory leaks podem ser ignoradas em programas que executam em curto período de tempo.

Concluindo, liberação só ocorre com FreeMem(ou Object.Free).

Nota: eu usei o termo variável, mas o mesmo se dá com qualquer local na memória.

Beppe


Responder

Gostei + 0

10/02/2004

Caninha51

Pelo que eu entendi...
Quando você atribui [b:0df44c45bf]Nil[/b:0df44c45bf] a um objeto, na verdade você está atribuindo ao local da memória que está fazendo referência a este objeto, correto??

E como ele(local) não está apontando pra lugar algum, depois de um tempo ele será liberado, é isso??E isto de certo modo não é liberar memória??


Não entendi, primeiro vc disse que nunca tinha ouvido nisso(o que meu professor falou) depois disse que pra liberar memória só com o Free!?

Então ele estava errado em dizer que [b:0df44c45bf]Nil[/b:0df44c45bf] apenas irá tirar a referência do objeto com o local de memória, e eu estava errado em achar que [b:0df44c45bf]Nil[/b:0df44c45bf] o liberaria da memória?


Grato,

[b:0df44c45bf]Caninha51[/b:0df44c45bf]


Responder

Gostei + 0

10/02/2004

Colutti

Vou ver se consigo tirar sua duvida:

Quando vc atribui NIL a algum objeto, na verdade vc esta retirando o ponteiro para onde este objeto esta alocado, mas este objeto ainda existe, vc so perde a referencia a ele. Exemplo:

form1 := tform1.create

aqui form1 recebe um endereco de memoria pra onde o objeto foi alocado, como:

showmessage(inttosrt(Integer(form1))) -> se isto fosse possivel vc teria algo como 144882 ...

quando vc faz

form1 := nil

na verdade esta apagando aquela referencia 144882, mas o objeto nesta posicao de memoria ainda existe ... entendeu?

Rafael


Responder

Gostei + 0

10/02/2004

Caninha51

Vamos supor um sistema que abre e fecha o mesmo form centenas de vezes ao dia...

O form1 eh criado e é reservado o local de memória X pra ele...
Vc atribui Nil a ele e o local X passa a ter referência a nenhum objeto, porém continua existindo, só sendo liberado no termino na aplicação...

Aí vc cria novamente o form1, e no lugar dele ser ´reapontado´ ao local X, não, agora eh reservado o local Y pra ele, e quando o form1 receber nil novamente, Y ficará ´orfão´ como o X...

E assim por diante....

Quer dizer que ao contrário de liberar memória(como várias pessoas, dicas, exemplos ensinam) ele faz eh sobrecarregar a memória.

Vcs concordam comigo???

Grato,

Caninha51


Responder

Gostei + 0

10/02/2004

Rmeusburger

Sim eu concordo com vc por isso semrpe que eu crio algo na mem eu verificao se já naum existe OK ...


Function fu_serverADO(AOwner: TComponent) : TADOConnection ;
Begin
if (TADOConnection(AOwner.FindComponent(´fu_serverADO´)) = nil) Then
begin
ConectionADO := TADOConnection.Create(AOwner);
ConectionADO.Name := ´fu_serverADO´;
ConectionADO.ConnectionString := Conn_String;
ConectionADO.Open();
end;
fu_serverADO := ConectionADO;
end;


Responder

Gostei + 0

10/02/2004

Colutti

o certo e voce criar e destruir, usando objeto.release ou objeto.destroy

Rafael Colucci


Responder

Gostei + 0

10/02/2004

Marconi

Desculpe voltar ao assunto, mas aprendi muito neste fórum e também sou um usuário do Nil achando que ele limpa a memória. O que aliás aprendi aqui mesmo.

A pergunta é: ´Quando apagamos um arquivo, o que na verdade acontece é apagar a referencia a ele, porém sabemos que ele continua la na HD, pois é assim que alguns programas conseguem recupera-lo. Mas como não existe mais referência a aquele bloco na FAT, o local acabará sendo utilizado por outro arquivo. Não seria isto também que acontece na memória ?´

Marconi


Responder

Gostei + 0

10/02/2004

Beppe

o certo e voce criar e destruir, usando objeto.release ou objeto.destroy Rafael Colucci


Peloamordedeus, não!

O Destroy não checa se o objeto existe, isto é, diferente de nil.
Já o Free sim, e só chama o Destroy na sequência quando necessário. O Free de TObject faz isso:
if Self <> nil then
  Self.Destroy;


Não entendi, primeiro vc disse que nunca tinha ouvido nisso(o que meu professor falou) depois disse que pra liberar memória só com o Free!?


Estava me referindo a esta sua indagação:
| Já ví várias dicas do tipo ´A melhor maneira de se liberar um form da
| memória´, etc.... E todas elas diziam pra atribuir o Nil ao form.

Se você tivesse lido com mais atenção teria visto que eu ratifiquei o que foi dito pelo seu professor, eu não discordei dele.

O nil não sobrecarrega(overloads) a memória. São apenas termos, mas quando usados devem ser usados no local certo. Uma variável do tipo objeto ocupa por si só 4 bytes, é um ponteiro disfarçado. Os objetos a qual se referênciam estão alocados em outro lugar. Bem, o resto já te respondi.

Pra exemplificar:
var
  A, B: TPessoa;
begin
  A := TPessoa.Create;
  A.Dormir(2.0);

  A := TPessoa.Create;         // uma memory leak acontece aqui

  B := A;
  A := TPessoa.Create;         // B continua referenciando o objeto anterior

  B := A;                      // B recebe um novo objeto. 
                               // agora sim uma memory leak

  A.Free;                      // B agora é uma dangling reference,
                               // pois aponta para um objeto destruído
end;



Responder

Gostei + 0

10/02/2004

Beppe

A pergunta é: ´Quando apagamos um arquivo, o que na verdade acontece é apagar a referencia a ele, porém sabemos que ele continua la na HD, pois é assim que alguns programas conseguem recupera-lo. Mas como não existe mais referência a aquele bloco na FAT, o local acabará sendo utilizado por outro arquivo. Não seria isto também que acontece na memória ?´


Marconi, isto existe há 40 anos e se chama Garbage Collection. Só não entendo por que uma linguagem visual como o Delphi não incorporou isso logo.
Porém, a especifição atual da linguagem não permite isso, sem que aja grandes mudanças(como as que ocorreram no Delphi for .NET, que tem GC)

Se você quer alguma coisa desse tipo, pode usar interfaces. Interfaces usam contagem de referências, mas esse método não garante a reclamação total de memória devido as referências cíclicas.

A diferença entre um sistema de arquivos(FS) e o gerenciador de memória(MM) do Delphi é que o MM não pode identificar(com certeza absoluta) onde estão os objetos usados, já que você pode armazenar o endereço de um objeto em um integer para depois converter de volta. Já o FS, até onde eu sei, só conhece arquivos e diretórios, e mantém uma lista explícita de blocos livres, em que a remoção de um arquivo faz com que o 1o. bloco do arquivo seja adicionado à esta lista.


Responder

Gostei + 0

10/02/2004

Caninha51

Ok, agora entendi!

Que isso sirva naum só pra mim, mas pra tantos outros, que como eu aprenderam que o Nil server para liberar o objeto da memória.

Usem o Free!! :))


Foi mal ae Beppe, se me espressei mal ou algo do tipo.

E Valew a todos!

Caninha51


Responder

Gostei + 0

10/02/2004

Beppe

Ok, agora entendi! Que isso sirva naum só pra mim, mas pra tantos outros, que como eu aprenderam que o Nil server para liberar o objeto da memória. Usem o Free!! :)) Foi mal ae Beppe, se me espressei mal ou algo do tipo. E Valew a todos! Caninha51


Tá tranquilo! :)

Só não pensei que tivesse alguém que achasse que o nil fosse liberar alguma memória... :o

T+


Responder

Gostei + 0

11/02/2004

Colutti

Detalhe:

O delphi tem Garbage Collection sim !!! O problema e que ele nao funciona para objetos, somente para tipos nativos (string, integer). Se ele nao tivesse garbage muitas coisas nao funcionariam, como por exemplo, as variaveis de procedure e functions nunca seriam desalocadas ... Por favor, cuidado com o uso inadequado do termo Garbage Collection.

Rafael COlucci


Responder

Gostei + 0

11/02/2004

Beppe

Detalhe: O delphi tem Garbage Collection sim !!! O problema e que ele nao funciona para objetos, somente para tipos nativos (string, integer). Se ele nao tivesse garbage muitas coisas nao funcionariam, como por exemplo, as variaveis de procedure e functions nunca seriam desalocadas ... Por favor, cuidado com o uso inadequado do termo Garbage Collection. Rafael COlucci


Hilário, cara! Devia postar isso no butequim... :lol:

Quem faz essa ´mágica´ é o [i:437f32d011]stack[/i:437f32d011], uma instrução de máquina dá conta do recado. Sob esta definição, então todas as linguagens tem GC. Strings tem o mesmo mecanismo de interfaces, mas como os componentes são apenas caracteres, funciona direitinho.

Delphi não tem mesmo GC para objetos. Estranho né? :roll: Será que você poderia explicar?


Responder

Gostei + 0

11/02/2004

Aroldo Zanela

Por favor, cuidado com o uso inadequado do termo Garbage Collection. Rafael COlucci


Exatamente, não vamos confundir [b:459bea6746]Escopo [/b:459bea6746]com [b:459bea6746]Garbage Collection[/b:459bea6746].


Responder

Gostei + 0

12/02/2004

Tnaires

Uma vez eu fiz um sistema q criava e destruía frames em tempo d execução. Havia dois botões: um para criar e outro para destruir. Enfrentei essa dúvida na época: qdo eu atribuía a variável q armazenava o objeto a nil, qdo criava d novo dava erro. Qdo eu usava o método Free, depois d um tempo dava erro.
Então, eu usei:
MeuObjeto.Free;
MeuObjeto := nil;

Pronto, testei o programa o dia todo, depurando passo a passo e verificando os conteúdos dos objetos (colocando o ponteiro do mouse sobre a variável e esperando) e não deu mais erro d memória.
Agora, qdo destruo objetos, uso sempre o Free, e logo após atribuo a variável a nil.


Responder

Gostei + 0

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

Aceitar