associação pythonbrasil[11] django zope/plone planet Início Logado como (Entrar)

FuncionamentoGarbageCollector

A linguagem Python disponibiliza um mecanismo de gerência de memória automático que é responsável por alocar memória para seus objetos e desalocá-la quando esses objetos não possuem mais referência para eles.

O mecanismo para a desalocação dessa memória fica implementado dentro do sistema de Garbage Collector.

De tempos em tempos o Garbage Collector do Python percorre a lista de objetos registrados verificando o número de referências para cada um deles. Quando esse número é zero (não existem mais referência para eles) o GC desaloca a memória usada por esse objeto. O mecanismo de contagem de referência funciona +/- assim:

   1 var1 = Objeto() # o objeto Objeto agora tem uma referência chamada var1
   2 
   3 var2 = var1 # o objeto Objeto agora tem duas referências para ele: var1 e var2
   4 
   5 var1 = OutroObjeto() # a referência de var1 agora pertence a 
   6                      # OutroObjeto, logo, Objeto agora tem só uma referência
   7 
   8 var2 = var1 # OutroObjeto agora tem 2 referências e o nosso bom e
   9             # velho Objeto não tem mais referência nenhuma para ele.
  10             # Desta forma fica impossível acessá-lo. Ele se perdeu
  11             # para sempre no 'limbo' da memória do computador.

Passado algum tempo (ou quando forçamos a execução do gc com um 'import gc; gc.collect()') o GC do Python vai encontrar esse objeto lá na memória e procederá o seguinte diálogo:

  • Objetinho, você está aí perdido? Onde estão as suas referências?
  • Ah, eu as perdi nos últimos comandos e agora estou aqui, perdido neste limbo...
  • Calma, não fique assim tão preocupado que eu vou te levar para um lugar muito melhor.
  • Não, eu quero ficar aqui porque minhas referências me disseram que não era pra eu conversar com estranhos!
  • Sinto muito, mas a minha função é recolher todo o li... digo... objetinho que perderam suas referências.
  • Eu não quero ir!
  • Neste caso terei que te matar!
  • NÃO!
  • Adeus objetinho... essa memória ficou pequena demais para nós dois.

E assim se foi o nosso Objeto :)

Além dessa maneira mais convencional de funcionamento o GC também trabalha de um outro método, mais lento, de coleta de lixo para eliminar objetos que perderam as suas referências externas mas possuem referência circular entre eles:

   1 class Obj(object):
   2   def __init__(self, ref = None):
   3      self.ref = ref
   4 
   5 a = Obj()
   6 b = Obj(a)
   7 c = Obj(b)
   8 a.ref = c

Desta forma os objetos referenciados por a, b e c além dessas referências também possuem a referência circular em seus respectivos 'self.ref'. O 'self.ref' de a aponta para c, o de c aponta para b e o de b aponta para a.

Agora apagaremos as referências a, b e c:

   1 del a
   2 del b
   3 del c

Cada um dos objetos ainda possuem pelo menos uma referência entre eles em 'self.ref', portanto os seus contadores de referência ainda não são zero mesmo que pra gente seja impossível acessá-los. Para resolver esse tipo de situação o GC tem um algorítmo mais esperto que percorre o círculo para identificar essa referência circular e desalocar esses objetos da memória.

O GC funciona nesse modo mais 'esperto' menos vezes do que o outro modo mais convencional e esse modo também consome uma quantidade muito grande de processamento. Portanto, ao fazer aplicações evite as referências circulares de objetos.