[RESOLVIDO]Coletor de lixo

Olá, pessoal!

Tenho uma dúvida com relação ao garbage collector.

Vou mostrar um programa e como eu pensei nele…

package com.wilson.garbagecollector;

import java.util.ArrayList;

class C1
{
	
}

class C2 extends C1
{
	
}

public class Teste 
{
	public static void main(String []args)
	{
		C1 a = new C1();
		C2 b = new C2();
		C1 c = new C2();
		
		ArrayList<C1> lista = new ArrayList<C1>();
		lista.add(a);
		lista.add(b);
		lista.add(c);
		lista.add(new C1());
		lista.add(lista.get(1));
		lista.add(lista.get(2));
		lista.remove(0);
		
		a = null;
		b = null;
		c = null;
		
		//AQUI
	}
}

Quais objetos são candidatos à varredura pelo GC no trecho “AQUI” ?

A minha dúvida é a seguinte. Eu aprendi (não sei se errado) que o garbage collector verifica se os objetos estão referenciando “null”. Caso estejam, são limpos por ele (a um tempo não uniforme, mas todo de uma vez).

O que andei lendo vai um pouco contra isso, pelo menos, no meu entendimento.

No código acima, vou representar a referência por uma seta, mesmo não existindo em Java:

a -> C1
b -> C2
c -> C2
lista -> ArrayList

O que li foi: quando faço:

a = null;
b = null;
c = null;

sobra apenas o objeto Arraylist para o GC recolher.

Eu pensava da seguinte maneira. Se a, b e c apontam para null, estes devem ser recolhidos pelo GC, e não ArrayList, que possui referência não nula…

Alguém poderia me explicar melhor isso?

GC coleta somente objetos que não estejam sendo referenciados.

O GC não recolhe variáveis, e sim Objetos.

O ArrayList é uma estrutura de dados que referencia outros objetos.

Logo se um objeto é referenciado pelo ArrayList, esse não pode ser recolhido.

O ArrayList somente seria recolhido se não houvesse ao menos uma variável que o referenciasse.

Espero que tenha ajudado.

[quote=JM4X]GC coleta somente objetos que não estejam sendo referenciados.

O GC não recolhe variáveis, e sim Objetos.

O ArrayList é uma estrutura de dados que referencia outros objetos.

Logo se um objeto é referenciado pelo ArrayList, esse não pode ser recolhido.

O ArrayList somente seria recolhido se não houvesse ao menos uma variável que o referenciasse.

Espero que tenha ajudado.[/quote]

Quando eu fiz:

a = b = c = null

Os objetos C1. C2 e C2 não deveriam ser capturados pelo GC?

[code]package com.wilson.garbagecollector;

import java.util.ArrayList;

class C1
{

}

class C2 extends C1
{

}

public class Teste
{
public static void main(String []args)
{
C1 a = new C1(); // Para fins de exemplo vamos chamar este de Objeto A
C2 b = new C2(); // Objeto B
C1 c = new C2(); // Objeto C

	ArrayList<C1> lista = new ArrayList<C1>();
	lista.add(a); // agora a lista também guarda a referência do Objeto A
	lista.add(b); // agora a lista também guarda a referência do Objeto B
	lista.add(c); // agora a lista também guarda a referência do Objeto C
	lista.add(new C1()); // a lista guarda a referência de um novo objeto
	lista.add(lista.get(1)); // guarda outra cópia da referência do Objeto B
	lista.add(lista.get(2)); // guarda outra cópia da referência do Objeto C
	lista.remove(0); // remove a referência do objeto A que estava no índice 0
	
	// As variáveis a, b e c não referenciam mais nenhum objeto
	a = null;
	b = null;
	c = null;
	
	// As variáveis a, b e c não guardam mais a referência dos objetos, porém a lista ainda guarda as referências do objeto B e C. Portanto apenas o objeto A fica elegível ao GC.
}

}[/code]

Comentei todo seu codigo identificando o que acontece a cada instrução dentro do main.

    package com.wilson.garbagecollector;  
      
    import java.util.ArrayList;  
      
    class C1  
    {  
          
    }  
      
    class C2 extends C1  
    {  
          
    }  
      
    public class Teste   
    {  
        public static void main(String []args)  
        {  
            C1 a = new C1();  // a variavel "a" aponta pra um novo objeto do tipo C1
            C2 b = new C2();  // a variavel "b" aponta pra um novo objeto do tipo C2
            C1 c = new C2();  // a variavel "c" aponta pra um novo objeto do tipo C2
              
            ArrayList<C1> lista = new ArrayList<C1>();  // a variavel "lista" aponta para um novo Objeto do tipo ArrayList
            lista.add(a); // o indice 0 do ArrayList apontado por "lista" aponta para o objeto apontado por "a"
            lista.add(b); // o indice 1 do ArrayList apontado por "lista" aponta para o objeto apontado por "b"
            lista.add(c); // o indice 2 do ArrayList apontado por "lista" aponta para o objeto apontado por "c"
            lista.add(new C1());  // o indice 3 do ArrayList apontado por "lista" aponta para um novo objeto do tipo C1
            lista.add(lista.get(1));  // o indice 4 do ArrayList apontado por "lista" aponta para o objeto apontado pelo indice 1
            lista.add(lista.get(2));  // o indice 5 do ArrayList apontado por "lista" aponta para o objeto apontado pelo indice 2
            lista.remove(0);  // o indice 0 do ArrayList apontado por "lista" deixa de apontar para o objeto que apontava
              
            a = null;  // a variavel "a" aponta pra null
            b = null;  // a variavel "a" aponta pra null
            c = null;  // a variavel "a" aponta pra null
              
            //AQUI  O OBJETO DO TIPO C1 INICIALMENTE APONTADO POR "a" ESTARIA DISPONIVEL PARA O GC.
        }  
    }

Espero que tenha ajudado.

HericYuzo.getCode.clone() // duplicamos código… ahuahuahuus num tinha visto seu post ainda. foi malz.

[quote=JM4X]Comentei todo seu codigo identificando o que acontece a cada instrução dentro do main.

    package com.wilson.garbagecollector;  
      
    import java.util.ArrayList;  
      
    class C1  
    {  
          
    }  
      
    class C2 extends C1  
    {  
          
    }  
      
    public class Teste   
    {  
        public static void main(String []args)  
        {  
            C1 a = new C1();  // a variavel "a" aponta pra um novo objeto do tipo C1
            C2 b = new C2();  // a variavel "b" aponta pra um novo objeto do tipo C2
            C1 c = new C2();  // a variavel "c" aponta pra um novo objeto do tipo C2
              
            ArrayList<C1> lista = new ArrayList<C1>();  // a variavel "lista" aponta para um novo Objeto do tipo ArrayList
            lista.add(a); // o indice 0 do ArrayList apontado por "lista" aponta para o objeto apontado por "a"
            lista.add(b); // o indice 1 do ArrayList apontado por "lista" aponta para o objeto apontado por "b"
            lista.add(c); // o indice 2 do ArrayList apontado por "lista" aponta para o objeto apontado por "c"
            lista.add(new C1());  // o indice 3 do ArrayList apontado por "lista" aponta para um novo objeto do tipo C1
            lista.add(lista.get(1));  // o indice 4 do ArrayList apontado por "lista" aponta para o objeto apontado pelo indice 1
            lista.add(lista.get(2));  // o indice 5 do ArrayList apontado por "lista" aponta para o objeto apontado pelo indice 2
            lista.remove(0);  // o indice 0 do ArrayList apontado por "lista" deixa de apontar para o objeto que apontava
              
            a = null;  // a variavel "a" aponta pra null
            b = null;  // a variavel "a" aponta pra null
            c = null;  // a variavel "a" aponta pra null
              
            //AQUI  O OBJETO DO TIPO C1 INICIALMENTE APONTADO POR "a" ESTARIA DISPONIVEL PARA O GC.
        }  
    }

Espero que tenha ajudado.

HericYuzo.getCode.clone() // duplicamos código… ahuahuahuus num tinha visto seu post ainda. foi malz.[/quote]

Muito obrigado pela ajuda!