Fórum Qual a Função do Nil? #212741
10/02/2004
0
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
Curtir tópico
+ 0Posts
10/02/2004
Beppe
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
Gostei + 0
10/02/2004
Caninha51
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]
Gostei + 0
10/02/2004
Colutti
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
Gostei + 0
10/02/2004
Caninha51
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
Gostei + 0
10/02/2004
Rmeusburger
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;
Gostei + 0
10/02/2004
Colutti
Rafael Colucci
Gostei + 0
10/02/2004
Marconi
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
Gostei + 0
10/02/2004
Beppe
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;
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;
Gostei + 0
10/02/2004
Beppe
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.
Gostei + 0
10/02/2004
Caninha51
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
Gostei + 0
10/02/2004
Beppe
Tá tranquilo! :)
Só não pensei que tivesse alguém que achasse que o nil fosse liberar alguma memória... :o
T+
Gostei + 0
11/02/2004
Colutti
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
Gostei + 0
11/02/2004
Beppe
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?
Gostei + 0
11/02/2004
Aroldo Zanela
Exatamente, não vamos confundir [b:459bea6746]Escopo [/b:459bea6746]com [b:459bea6746]Garbage Collection[/b:459bea6746].
Gostei + 0
12/02/2004
Tnaires
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.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)