Coletor de Lixo


Tornando Objetos Visíveis para a Coleta de Lixo Explicitamente: Referência Nula

Um objeto se torna elegível para a Coleta de Lixo quando não há mais referência a ele. A primeira maneira de remover a referência de um objeto é setando-o como null.

public class Buffer {
      public static void main(String[] args) {
            StringBuffer sb = new StringBuffer("s");
            /* quando uma variável deixa de apontar
             * para um objeto recebendo o valor null,
             * esse objeto passará a ficar visível para
             * o coletor de lixo*/
            sb = null;
      }
}

Tornando Objetos Visíveis para a Coleta de Lixo Explicitamente: Reatribuindo uma Variável de Referência

É possível dissociar uma variável de referência de um objeto reatribuindo a variável de referência para outro objeto; ou seja, uma variável em determinado momento aponta para o objeto1, ao ser reatribuída para o objeto2, o objeto1 ficará disponível para o coletor, pois não possui mais uma variável de referência apontando para ele.
Variáveis locais são criadas quando o método é invocado, da mesma forma, quando o compilador chega ao final da execução do método, essas variáveis ficam disponíveis para a Coleta de Lixo. Entretanto, existe uma exceção: se um objeto é retornado do método, sua referência será reatribuída à variável de referência que está esperando o retorno, ou seja, essa referência da variável local não ficará elegível.

import java.util.Date;

public class Coletor {

      public static void main(String[] args) {
            StringBuffer s1 = new StringBuffer("s1");
            StringBuffer s2 = new StringBuffer("s2");
            /* quando uma variável deixa de apontar
             * para um objeto e passar a apontar para
             * outro, o primeiro não terá mais nenhuma
             * variável apontando para ele e passará a
             * ficar visível para o coletor; nesse caso
             * o s1. */
            s1 = s2;
           
            Date data = new Date();
            setDate(data);
           
            Date data2 = new Date();
            /* recebe a referência da variável local
             * que é retornada do método */
            data2 = getDate();
      }
     
      /* variáveis locais ficam visíveis para o
       * coletor quando o método termina a execução */
      static void setDate(Date dt) {
            System.out.println(dt);
      }
     
      /* quando o método retorna um objeto, na verdade
       * retorna a referência, o que faz com que a
       * variável local não fique visível para o
       * coletor, já que essa referência não mais
       * ficará perdida ao ser reatribuída a outra
       * variável */
      static Date getDate() {
            return new Date();
      }

}

Tornando Objetos Visíveis para a Coleta de Lixo Explicitamente: Isolando uma Referência

Numa classe onde existem objetos que são instância dessa mesma classe, se esses objetos referenciarem um ao outro e depois receberem atribuições null, eles estarão disponíveis para a Coleta de Lixo.

Forçando a Coleta de Lixo

Não existe uma maneira direta de forçar a coleta, mas existem métodos que permitem a JVM chamar a coleta de lixo. Porém isso não é garantido de imediato, mas o compilador irá tentar atender a requisição o mais rápido possível.
As rotinas que compõem o coletor de lixo são da classe Runtime, que é uma classe especial que contém um único objeto (a Singleton) para cada programa main.
O objeto Runtime oferece um mecanismo para comunicação direta com a máquina virtual. Para pegar a instância de Runtime é possível usar o método Runtime.getRuntime(), que retorna o Singleton.
O objeto singleton pode invocar o coletor através do método gc(). Alternativamente, é possível chamar o mesmo método da classe System (System,gc();).

import java.util.Date;

public class GC {
      public static void main(String[] args) {
            Runtime rt = Runtime.getRuntime();
            //um objeto na memória
            Date d = new Date();
            //passa a ficar visível para o coletor
            d = null;
            /* indica ao coletor q é necessário limpar
             * a memória do q n está sendo utilizado*/
            rt.gc();
           
            //outra forma de chamar o coletor
            System.gc();
      }
}

Limpando antes do Coletor de Lixo - O método finalize()

Java fornece um mecanismo para executar algum código antes do objeto ser excluído pelo coletor. Esse código está no método finalize(), que todas as classes herdam da classe Object.
Isso soa uma grande idéia, pois se o objeto abriu alguns recursos e é necessário fechá-los antes que o objeto seja destruído, essa é uma boa opção.
O problema é que não se sabe o momento que o coletor irá destruir os objetos, ou se até mesmo o fará, ou seja, não se pode garantir que o código que estiver dentro do finalize() será executado.
Regras: para qualquer objeto o método finalize() será chamado apenas uma vez pelo coletor; chamar o método finalize() pode resultar em salvar o objeto da destruição; se o objeto não for destruído, quando ficar elegível novamente para o coletor, este não executará mais o finalize().


Fonte: SCJP Sun Certified Programmer for Java 6 Study Guide

0 comentários:

Postar um comentário