Dúvida garbage collection

17 respostas
ribclauport

Bom pessoal estou com uma dúvida em coletor de lixo, por exemplo, seu eu tiver uma classe A e B relacionadas da seguinte forma:

public class A{
 B bDeA = new B();
}

class B{
 A aDeB = new A();
}

public class TestIlhas{

 public static void main(String[] args){
    A a = new A();
    B b = new B();
    b.aDeB = a;
    a = null; //linha 1
    // mais codigo
   
  }

}

A minha pergunta é, o objeto referenicado por a vai estar elegível para o gargabe colector quando a linha 1 for executada? o fato do objeto a ter uma referência a um objeto b, no caso “aDeB” influencia em algo?

Obrigado a Todos.

17 Respostas

drsmachado

Segundo a teoria do garbage collector, sim. Após a linha marcada como linha 1 ser executada, todas as threads que referenciavem o objeto a deixam de fazê-lo. O que existe, ainda, é um objeto cópia de a, na variável aDeB.

L

Ele ainda continua com uma referencia

A a = new A();

B b = new B();

b.aDeB = a;  // aqui vc estaria recebendo uma nova referenia ao Objeto A e deixando a antiga referencia um candidato ao GB

a = null; //linha 1
// agora aqui vc ainda tem essa referencia na variavel de B

Assim vc tem uma referencia na memoria stack algo apontando para o Objeto na memoria heap
Qualquer coisa da uma olhada nesse post
http://www.guj.com.br/java/208564-memoria-heap-vs-stack

ribclauport

Certo…

Bom, se fosse o objeto b, ou seja b tem uma refereência ao objeto “a”, mais agora foi marcado como null, ele também iria ser elegível, desculpe a insistência.

public class A{   
B bDeA = new B();   
}   
  
class B{   
A aDeB = new A();   
}   
  
public class TestIlhas{   
  
public static void main(String[] args){   
    A a = new A();   
    B b = new B();   
    b.aDeB = a;   
    b = null; //linha 1   
    // mais codigo   
     
  }   
  
}
ribclauport

drsmachado, por favor, me responda uma coisa, o fato desta linha existir:

b.aDeB = a;

não faz com que a referência aDeB, aponte para o objeto “a”, fazendo com que o mesmo deixe de ser elegível ao Garbage?

bom a outra dúvida também que postei acima é no caso de ser setado uma variavel null, porém esta variável aponta para um objeto que tem uma referência internamente que ainda esta “viva”

A a = new A();     
    B b = new B();     
    b.aDeB = a;     
    b = null; //linha 1

O fato de b ter um “aDeB”, não impede que ele seja elegível?

Descupem a confusão.

L

Então,

Se na memoria stack uma variavel de referencia apontando para a memoria heap vc ainda tem o objeto

b.aDeB = a; //por causa dessa linha o objeto a ainda existe
a = null; // vc perde 1 referencia mais não a outra

agora nesse segundo exemplo
b = null //ele passa a não ter mais uma referencia na memoria stack então assim ele é um forte candidato ao GB

ribclauport

leulseixas, Obrigado pela explicação, a dúvida era mesma quanto a variável interna de b, ou seja b esta null, mais dentro de b tinha uma outra variável…

Valeu.

L

ribclauport:
leulseixas, Obrigado pela explicação, a dúvida era mesma quanto a variável interna de b, ou seja b esta null, mais dentro de b tinha uma outra variável…

Valeu.

Opa, bem essa pergunta foi boa para dar um no na cabeça mesmo rsrsrs,
mais por 99,9% de certeza acho que o objeto a pode ser um forte candidato,
como vc falou o objeto b tem uma variavel que aponta para o objeto a
quando b for coletado nada mais aponta para a então a morre tbm.

De verdade vou dar uma estudada sobre isso mais acho que seria assim.

ViniGodoy

Lembre-se que objetos (e seus atributos) só existem no heap, nunca no Stack.
Apenas as referências e tipos primitivos podem existir no stack.

B.aDeB é uma referência, mas como é um atributo de um objeto, existe no heap.

Portanto, assim que B se torna elegível, B é coletado.
A não será coletado, pois existe a variável a, no stack (criada na linha 12). O que ocorre com A é que simplesmente seu contador de referências será decrementado, pois agora não há mais a referência de aDeb. A se torna elegível assim que a variável “a” ficar nula.

rmendes08

leulseixas:
ribclauport:
leulseixas, Obrigado pela explicação, a dúvida era mesma quanto a variável interna de b, ou seja b esta null, mais dentro de b tinha uma outra variável…

Valeu.

Opa, bem essa pergunta foi boa para dar um no na cabeça mesmo rsrsrs,
mais por 99,9% de certeza acho que o objeto a pode ser um forte candidato,
como vc falou o objeto b tem uma variavel que aponta para o objeto a
quando b for coletado nada mais aponta para a então a morre tbm.

De verdade vou dar uma estudada sobre isso mais acho que seria assim.

Um jeito simples de enunciar a regra é o seguinte:

“Um objeto é elegível para coleta de lixo quando ele NÃO é alcançável a partir da pilha de alguma thread em execução”.

Nesses casos, a melhor maneira de enxergar isso é tentar desenhar o grafo das referências, caso você consiga navegar até um objeto partindo da pilha esse objeto não é elegível para GC.

ribclauport

Obrigado Viny e rmendes08, pelas ótimas explicações.

Viny, por favor, tenho uma dúvida antiga quanto a isto:

Posso fazer a afirmação abaixo conforme a interpretação do seu texto?

aDeB, é uma referência a um objeto que está no heap, então aDeB(referência) está no Stack.

Obrigado.

ViniGodoy

No Java, o stack tem apenas variáveis locais primitivas e referências, criadas na forma de variáveis locais.
aDeB é um atributo de um objeto, e não uma variável local, portanto, está no heap.

Você programava em C++?

L

rmendes08:
leulseixas:
ribclauport:
leulseixas, Obrigado pela explicação, a dúvida era mesma quanto a variável interna de b, ou seja b esta null, mais dentro de b tinha uma outra variável…

Valeu.

Opa, bem essa pergunta foi boa para dar um no na cabeça mesmo rsrsrs,
mais por 99,9% de certeza acho que o objeto a pode ser um forte candidato,
como vc falou o objeto b tem uma variavel que aponta para o objeto a
quando b for coletado nada mais aponta para a então a morre tbm.

De verdade vou dar uma estudada sobre isso mais acho que seria assim.

Um jeito simples de enunciar a regra é o seguinte:

“Um objeto é elegível para coleta de lixo quando ele NÃO é alcançável a partir da pilha de alguma thread em execução”.

Nesses casos, a melhor maneira de enxergar isso é tentar desenhar o grafo das referências, caso você consiga navegar até um objeto partindo da pilha esse objeto não é elegível para GC.

opa vlw então fui nessa linha de pensamento.
Valeu!!!

ribclauport

Viny, eu não progamava em C++,
na verdade a dúvida é realmente em função da “instanciação” e da referência, no caso o lado direito e esquerdo da linha abaixo

public class A{     
B bDeA = new B();     // aqui tem uma referência chamada bDeA, e para onde vai esse "bDeA", o new B(), criou um objeto no heap, mas e o "bDeA"
}

bom deixei bem redundante para realmente configurar a dúvida, este “tipo” bDeA, vai para onde?
Sei que existe o objeto B no heap, já que foi dado um “new”, mas e a referência chamada “bDeA”, tá onde?

Obrigado Viny, e desculpe a ignorância.

L

ViniGodoy:
Lembre-se que objetos (e seus atributos) só existem no heap, nunca no Stack.
Apenas as referências e tipos primitivos podem existir no stack.

B.aDeB é uma referência, mas como é um atributo de um objeto, existe no heap.

Portanto, assim que B se torna elegível, B é coletado.
A não será coletado, pois existe a variável a, no stack (criada na linha 12). O que ocorre com A é que simplesmente seu contador de referências será decrementado, pois agora não há mais a referência de aDeb. A se torna elegível assim que a variável “a” ficar nula.

Sim foi o que falei mais isso seguindo o segundo exemplo,
No primeiro exemplo b não recebia null então o objeto no heap não seria coletado pela referencia da variavel do b que recebeu a copia de da referencia de a

ViniGodoy
public class A{     
    // Isso é uma propriedade de A, portanto, será criada somente quando A for criada
    B bDeA = new B();     
}

Ou seja, quando você faz:
[code]A a = new A(); //O new cria um A e roda aquele código[/quote]

Você cria bDeA dentro daquele new. Se é dentro do new, é no heap.

ribclauport

Ok, obrigado pela explicação.

marcosSC

Pessoal estou com uma dúvida:

Uma variável static pode se tornar elegível ao Garbage collection? por exemplo:

class A{

…

}
class B{

static A a;

a = null;  // aqui a variável pode ser coletada pelo GC?

}
Criado 17 de abril de 2012
Ultima resposta 18 de set. de 2012
Respostas 17
Participantes 6