Linha de comportamento do coletor de lixo (recuperador de memória)
O programador Java não precisa monitorar a alocação de memória porque o coletor de lixo gerencia a memória automaticamente. O Garbage Collector é executado pela Java Virtual Machine (JVM). O coletor de lixo é um processo de baixa prioridade executado periodicamente e libera memória usada por objetos que não são mais necessários. Diferentes JVMs possuem diferentes algoritmos de coleta de lixo. Existem vários algoritmos usados, por exemplo: algoritmo de contagem de referência ou algoritmos de marcação e raspagem.
Executando o coletor de lixo em Java
A JVM normalmente executa o coletor de lixo quando a memória livre está baixa. Mas o funcionamento do coletor de lixo não garante que sempre haverá memória livre suficiente. Se não houver memória suficiente mesmo após a recuperação, a JVM lançará uma exceção OutOfMemoryError. Observe que a JVM deve executar o coletor de lixo pelo menos uma vez antes de lançar uma exceção. Você pode solicitar que o coletor de lixo seja executado em Java, mas não pode forçar essa ação.
Solicitação para executar o coletor de lixo
Para fazer uma solicitação, você pode chamar um dos seguintes métodos:
System.gc()
Runtime.getRuntime().gc()
Adequação para executar o coletor de lixo
Um objeto deve ser descartado quando não estiver mais disponível para o fluxo vivo. Um objeto pode estar sujeito a descarte em diferentes casos:
- Se uma variável de tipo de referência que se refere a um objeto for definida como "0", o objeto deverá ser descartado se não houver outras referências a ele.
- Se uma variável de um tipo de referência que se refere a um objeto for criada para se referir a outro objeto, o objeto deverá ser descartado se não houver outras referências a ele.
- Os objetos criados localmente em um método são descartados quando o método é encerrado, a menos que sejam exportados desse método (ou seja, retornados ou lançados como uma exceção).
- Objetos que fazem referência entre si podem estar sujeitos a descarte se nenhum deles estiver disponível para o thread ativo.
Vejamos um exemplo:
public class TestGC
{
public static void main(String [] args)
{
Object o1 = new Integer(3);
Object o2 = new String("Tutorial");
o1 = o2;
o2 = null;
}
}
Neste exemplo
Integer
, o objeto (inteiro) originalmente referenciado por o1 pode ser descartado após a linha 3 porque o1 agora se refere ao objeto
String
(string). Embora o2 seja criado para se referir a nulo, o objeto
String
(string) não é reciclável, pois o1 se refere a ele.
Finalização
A tecnologia Java permite usar um método
finalize()
(finalizar) para fazer a limpeza necessária antes que o coletor de lixo recupere um objeto da memória. Este método é chamado em um objeto pelo coletor de lixo quando o coletor de lixo determina que não há mais referências ao objeto. Isso está descrito na classe
Object
, o que significa que é herdado por todas as classes. A subclasse substitui o método
finalize()
para se libertar dos recursos do sistema ou para outra limpeza:
protected void finalize() throws Throwable
Se uma exceção não registrada for lançada pelo método
finalize()
, a exceção será ignorada e a finalização desse objeto será interrompida. O método
finalize()
só será invocado uma vez durante a vida útil do objeto. É possível usar um método
finalize()
em qualquer objeto para protegê-lo contra descarte. Mas neste caso, o coletor de lixo não está mais ativado
finalize()
para este objeto. O método
finalize()
sempre será invocado uma vez antes do objeto ser coletado como lixo. Porém, é possível que o método
finalize()
não seja ativado para um determinado objeto durante toda a sua existência, uma vez que não pode ser descartado.
Resumo
Nesta seção, examinamos o processo de coleta de lixo, que é uma técnica de gerenciamento de memória na linguagem Java. A coleta de lixo não pode ser forçada. Aprendemos sobre as diferentes maneiras de tornar os objetos elegíveis para reciclagem e aprendemos que o método
finalize()
é invocado antes do objeto ser recuperado pelo coletor de lixo.
Exercício
Pergunta: Quantos objetos estarão sujeitos a descarte após a linha 7?
public class TutorialGC
{
public static void main(String [] args)
{
Object a = new Integer(100);
Object b = new Long(100);
Object c = new String("100");
a = null;
a = c;
c = b;
b = a;
}
}
Opções de resposta: A. 0 B. 1 C. 2 D. 3 E. O código não pode ser compilado
Opção correta: B
Explicação: Dos três objetos criados nas linhas 1, 2 e 3, apenas o objeto
Integer
deve ser descartado no fim da linha 7. Referências de variáveis, a, que originalmente referenciavam o objeto
Integer
, referenciam o objeto
String
na linha 5. Assim,
Integer
o objeto deve ser descartado após a linha 5, pois não há variáveis que o façam referência. Variáveis
b
e
c
referem-se a objetos
String
e
Long
objetos das linhas 6 e 7, portanto não são recicláveis.
GO TO FULL VERSION