what is garbage collection java
Este tutorial explica o que é Garbage Collection em Java e como funciona o Garbage Collector. Você também aprenderá sobre Algoritmos para Coleta de Lixo:
Os leitores com conhecimento em C / C ++ devem estar cientes de que é responsabilidade do programador criar e deletar os objetos em C / C ++.
Erros graves surgem se o programador se esquece de destruir os objetos criados. Isso ocorre porque a falha em destruir os objetos pode causar “ Fora da memória ”Erros, vazamentos de memória, etc.
Essa situação é totalmente resolvida em Java, pois não há necessidade de um programador manter um controle dos objetos. Java cuida da destruição de objetos para nós por meio da coleta de lixo automática.
=> Visite aqui para aprender Java do zero.
O processo pelo qual os objetos que não estão mais em uso são removidos da memória heap é denominado “Coleta de Lixo”. A técnica de coleta de lixo é uma parte do gerenciamento de memória em Java.
Assim, em Java, o Garbage Collector destrói todos os objetos que não estão mais em uso.
O que você aprenderá:
- O que é um coletor de lixo em Java?
- Como funciona a coleta de lixo em Java?
- Algoritmos de coleta de lixo em Java
- Conclusão
O que é um coletor de lixo em Java?
A coleta de lixo em Java é gerenciada por um programa chamado Garbage Collector.
O Garbage Collector pode ser definido como um programa usado para gerenciar a memória automaticamente, tratando da desalocação do objeto.
Sabemos que na linguagem Java, os novos objetos são criados e alocados na memória usando o novo operador. A memória alocada para um objeto usando um novo operador permanece alocada até que as referências estejam usando este objeto.
Assim que as referências deixam de existir, a memória que o objeto ocupa é recuperada. Java então lida com a desalocação ou destruição de objetos automaticamente e não precisamos destruir explicitamente o objeto.
Essa técnica é a técnica Garbage Collection em Java, em que os programadores não precisam lidar com a desalocação de objetos explicitamente.
Observe que se os programas não desalocarem a memória quando os objetos não precisarem dela, então eventualmente não haverá memória para alocar e os programas irão travar. Essa situação é chamada de vazamento de memória.
O coletor de lixo sempre é executado em segundo plano em um encadeamento daemon. O Garbage Collector é considerado o melhor exemplo do encadeamento daemon.
O Garbage Collector é executado com a intenção de liberar a memória heap. Ele faz isso destruindo os objetos que são “inacessíveis”.
O que é um objeto “inacessível”?
Um objeto se torna inacessível quando não há nem mesmo uma única referência associada a ele.
Considere o seguinte trecho de código:
Integer ref_obj = new Integer (5); //ref_obj is a reference to Integer ref_obj = null; //Integer object now becomes unreachable
Como visto no código acima, um objeto é alcançável desde que uma referência esteja associada a ele. No momento em que a associação de referência é removida (uma referência de configuração para nulo no caso acima), o objeto se torna inacessível.
Quando um objeto se torna inacessível, ele se torna elegível para a coleta de lixo (GC).
Como podemos tornar um objeto elegível para GC?
Embora o programador não seja obrigado a destruir os objetos porque eles são cuidados pelo GC, pelo menos o programador pode tornar esses objetos inacessíveis quando não forem mais necessários.
Ao fazer isso, o GC irá coletar os objetos inacessíveis e destruí-los.
Existem algumas maneiras de tornar um objeto elegível para GC, tornando-o inacessível.
Eles são:
# 1) Anular a referência
Dada uma referência atribuída a um objeto, se esse objeto não for mais necessário, atribua a referência a nulo.
Student s = new Student (); s = null;
Quando s é definido como nulo, o objeto Aluno fica inacessível.
# 2) Reatribuir a referência
Esta é outra maneira de tornar os objetos elegíveis para GC.
Considere o seguinte código.
Student s1 = new Student (); Student s2 = new Student (); s1 = s2;
Agora, como atribuímos s1 a outro objeto, o objeto Aluno referenciado por s1 é desreferenciado.
# 3) Crie um objeto anônimo
Ao criar um objeto anônimo, podemos tornar os objetos elegíveis para GC.
Podemos criar um objeto anônimo conforme mostrado abaixo:
new Student();
Depois de tornar os objetos elegíveis para GC, esses objetos podem ou não ser destruídos imediatamente pelo GC. Isso ocorre porque não podemos forçar explicitamente o GC a executar como e quando queremos.
Quando o coletor de lixo é executado?
Cabe à JVM executar o programa Garbage Collector. Quando a JVM executa o Coletor de Lixo, os objetos inacessíveis são destruídos. Mesmo assim, não podemos garantir quando o JVM será executado.
Embora não possamos forçar a execução do GC, podemos muito bem solicitar uma coleta de lixo.
O GC pode ser solicitado usando qualquer um dos seguintes métodos.
# 1) System.gc (): A classe System do Java fornece um método estático gc () usando o qual podemos solicitar que a JVM execute o Garbage Collector.
# 2) Runtime.getRuntime (). Gc (): Como System.gc (), também podemos usar o método gc () da “Classe de tempo de execução” para solicitar que a JVM execute o Garbage Collector.
Nota: Não há garantia de que o Coletor de Lixo será executado após uma solicitação desses dois métodos.
Finalização
A finalização é executada pelo Garbage Collector antes de destruir os objetos. Como parte da técnica de finalização, o Garbage Collector chama o método finalize () no objeto. O método finalize () é usado para realizar atividades de limpeza.
O método finalize () é fornecido pela classe “Object” e possui o seguinte protótipo.
protected void finalize () throws Throwable
O método finalize () é invocado sempre que o objeto é coletado como lixo
Nota: O coletor de lixo coleta apenas os objetos criados com a nova palavra-chave. Para outros objetos, temos que usar o método finalize () para realizar a limpeza.
O programa a seguir mostra uma coleta de lixo simples em Java.
class TestGC{ @Override // finalize method: called on object once // before garbage collecting it protected void finalize() throws Throwable { System.out.println('Garbage collector called'); System.out.println('Object garbage collected : ' + this); } } class Main{ public static void main(String args()){ TestGC gc1=new TestGC(); TestGC gc2=new TestGC(); gc1 = null; //nullify gc1 System.gc(); //request for GC to run gc2 = null; //nullify gc2 Runtime.getRuntime().gc(); //request for GC to run } }
Resultado
No programa acima, criamos uma classe TestGC. Nesta classe, substituímos o método finalize (). Então, na classe principal, criamos dois objetos da classe TestGC. Primeiro, anulamos um objeto e chamamos System.gc () para solicitar o Garbage Collector.
Em seguida, anulamos o segundo objeto e chamamos o método Runtime.getRuntime.gc () para solicitar o Garbage Collector. A saída mostra a saída do método finalize duas vezes, indicando que o Coletor de Lixo foi executado duas vezes.
Nota: Embora tenhamos essa saída, não é garantido que obteremos sempre a mesma saída. Depende completamente da JVM.
Como funciona a coleta de lixo em Java?
Nesta seção, veremos como a coleta de lixo funciona em Java.
Durante a coleta de lixo, o Coletor de lixo procura a memória Heap e então “marca” os objetos inacessíveis. Então isso os destrói.
Mas o problema surge quando o número de objetos aumenta. Conforme os objetos aumentam, o tempo gasto para a Coleta de Lixo também aumenta, pois ela procura por objetos inacessíveis. No entanto, não afeta muito, pois a maioria dos objetos tem vida útil curta.
O comportamento acima é chamado “Coleta de lixo geracional” e deve melhorar o desempenho da JVM. Nesta abordagem, todo o espaço do Heap é dividido em - Geração jovem, Geração antiga ou estável e Geração permanente.
# 1) Espaço de heap da geração jovem: Todos os novos objetos são criados neste espaço. Uma vez que o espaço está cheio, Minor GC ocorre, onde todos os objetos mortos são destruídos. O processo menor de GC é rápido e rápido, pois a maioria dos objetos está morta. Os objetos que sobrevivem à geração jovem são transferidos para as gerações anteriores.
# 2) Espaço de heap da velha geração: Esta geração armazena objetos que sobrevivem por muito tempo. Quando a idade limite definida para a geração jovem é atingida, o objeto é movido para a geração anterior. Quando o espaço da geração anterior é preenchido, um GC principal é executado.
O GC principal é lento porque os objetos envolvidos aqui são objetos vivos. Às vezes, todo o espaço do Heap que inclui as gerações jovens, bem como as velhas, é limpo. Isso é chamado de “GC Completo”.
# 3) Geração Permanente L Até o Java 7 existia uma Geração Permanente (Perm Gen). Os metadados mantidos do Perm Gen foram usados pela JVM. A JVM usou esses metadados para descrever classes e métodos usados no aplicativo. O Perm Gen foi removido no Java 8.
Coleta de lixo Java 8: Perm Gen e Metaspace
Já mencionamos sobre o espaço Perm Gen que estava presente até o Java 7. Porém, agora no Java 8, o JVM representa os metadados da classe usando a memória nativa chamada “Metaspace”.
Além do Metaspace, existe um novo sinalizador chamado “MaxMetaspaceSize” que limita a memória usada para os metadados da classe. Se nenhum valor for especificado para MaxMetaspaceSize, o Metaspace o redimensionará em tempo de execução de acordo com a demanda do aplicativo.
Quando o espaço de metadados da classe atinge MaxMetaspaceSize, o Metaspace GC é acionado. Quando há Metaspace GC excessivo, isso indica vazamento de memória de classes, carregadores de classe, etc., bem como dimensionamento inadequado.
Algoritmos de coleta de lixo em Java
Existem várias maneiras de executar a coleta de lixo. Nesta seção, apresentaremos quatro dessas formas ou algoritmos para Coleta de Lixo em Java.
GC serial
Serial GC é o algoritmo de GC mais simples. Ele funciona principalmente em pequenos tamanhos de heap e sistemas de thread único. Enquanto trabalha, o Serial GC congela todos os aplicativos.
Para ligar o GC serial, podemos usar a seguinte opção JVM.
o que é um plano de teste no qa
java –xx:+UseSerialGC –jar Application.java
O comando acima pode ser fornecido na linha de comando. Aqui, Application.java é um arquivo para o qual o GC serial deve ser habilitado.
Taxa de transferência / GC paralelo
O algoritmo Parallel GC é o padrão no JDK 8. Este algoritmo usa vários threads para varrer o espaço de heap e compactar. Esse algoritmo é adequado principalmente para aplicativos que podem lidar com pausas de thread e otimizar a sobrecarga da CPU.
Uma desvantagem do GC paralelo é que, durante a execução do GC secundário ou completo, o algoritmo pausa os encadeamentos do aplicativo.
O coletor CMS
O CMS significa “ Varredura de Marca Simultânea ”. Este algoritmo faz uso de vários concorrente threads para verificar o heap ( marca ) para identificar objetos não utilizados e reciclar ( varrer ) eles. O coletor CMS possui um modo Stop-The-World (STW).
O coletor entra neste modo em dois cenários:
- Quando objetos pertencentes à geração anterior podem ser alcançados a partir de variáveis estáticas ou pontos de entrada de thread. Portanto, este modo está ativado durante a inicialização das marcações de raiz iniciais.
- Quando o algoritmo está sendo executado simultaneamente, o aplicativo altera o estado e força o coletor a voltar para se certificar de que os objetos corretos estão marcados.
O coletor CMS, entretanto, pode sofrer “falhas de promoção”. Então, o que é um fracasso promocional? Se os objetos do espaço da geração jovem forem movidos para a geração anterior, e o coletor não tiver criado espaço suficiente para esses objetos no espaço de heap da geração anterior, ocorrerá uma falha promocional.
Para evitar falha promocional, podemos fornecer mais threads de segundo plano ao coletor ou fornecer mais tamanho de heap à geração anterior.
O Colecionador G1
O Coletor G1 é o Coletor “Primeiro o Lixo”. Ele é projetado para tamanhos de heap de mais de 4 GB. Com base no tamanho do heap, ele divide o tamanho do heap em regiões de tamanhos que variam de 1 MB a 32 MB.
O coletor G1 marca os objetos em função da vivacidade dos objetos ao longo do monte. Após essa fase de marcação, G1 fica atento às regiões vazias. Assim, ele coleta os objetos inacessíveis dessas regiões, liberando assim uma grande quantidade de espaço. Por isso, ele é denominado Garbage-First, pois coleta primeiro as regiões que contêm o lixo.
Ele também atende ao objetivo de tempo de pausa definido pelo usuário usando um modelo de previsão de pausa, selecionando o número de regiões a serem coletadas, dependendo do objetivo de tempo de pausa especificado.
Vantagem da coleta de lixo
- A coleta de lixo torna o gerenciamento de memória em Java eficiente, pois remove objetos não referenciados da memória heap sem a interferência do programador.
- Como a coleta de lixo é automática e faz parte da JVM, nenhum esforço extra é necessário do programador para recuperar memória ou destruir objetos.
- O programador não precisa escrever nenhum código específico para desalocar a memória e excluir objetos como feito em C / C ++.
perguntas frequentes
P # 1) Qual é a função de um coletor de lixo?
Responda: Em Java, o Garbage Collector é a parte principal no gerenciamento de memória e tem a tarefa de coletar os objetos inacessíveis e recuperar a memória.
P # 2) O que você quer dizer com coleta de lixo?
Responda: A coleta de lixo é a técnica pela qual a memória é gerenciada automaticamente, recuperando a memória não utilizada. É um recurso presente em linguagens de programação como Java, devido ao qual os programadores não precisam rastrear os objetos não utilizados e destruí-los. Isso é feito automaticamente usando a coleta de lixo.
Q # 3) Quem é o responsável pela coleta de lixo em Java?
Responda: O gerenciamento de memória Java é de responsabilidade da Garbage Collection.
Q # 4) Como podemos evitar a coleta de lixo em Java?
Responda: Como o Garbage Collector não recupera a memória de variáveis / objetos que estão ativos, a melhor maneira de evitar a Garbage Collection é continuar usando variáveis / objetos em todo o programa.
Q # 5) Como você pode ter certeza de que um objeto é Coletado como lixo?
Responda: Um objeto é elegível para a coleta de lixo quando está inacessível, ou seja, quando não há mais referências se referindo ao objeto. Embora não possamos forçar o Garbage Collector a ser executado sempre que quisermos, podemos sempre solicitar que ele seja executado usando System.gc ().
Conclusão
A Garbage Collection in Java que discutimos neste tutorial é automática e o programador não precisa se preocupar em excluir os objetos ou variáveis alocados no programa.
A coleta automática de lixo em Java é o recurso mais importante da linguagem e faz parte do gerenciamento de memória em Java.
Embora a coleta de lixo seja realizada por JVM e esteja fora do alcance do programador, podemos sempre solicitar que o coletor de lixo seja executado usando o método gc () da classe System e Runtime.
Neste tutorial, discutimos o processo de finalização que é executado antes que os objetos sejam destruídos pelo Coletor de Lixo. Também discutimos o processo de coleta de lixo em Java. Finalmente, discutimos os vários algoritmos usados pelo Coletor de Lixo.
Isso conclui nossa discussão sobre Garbage Collector em Java.
=> Veja a série de treinamento simples em Java aqui.
Leitura recomendada
- Java Basics: Java Syntax, Java Class e Core Java Concepts
- Para que serve o Java: 12 aplicativos Java do mundo real
- Tutorial de Java String | Métodos Java String com exemplos
- Tutorial JAVA para iniciantes: mais de 100 tutoriais práticos em vídeo Java
- Componentes Java: plataforma Java, JDK, JRE e máquina virtual Java
- Implantação Java: Criação e execução de arquivo JAR Java
- Java Virtual Machine: como a JVM ajuda na execução de aplicativos Java
- Tutorial de reflexão Java com exemplos