image

Bolsas de estudo DIO PRO para acessar bootcamps ilimitados

Disponível apenas:

12 vagas
Article image
Thiago Pompeu
Thiago Pompeu25/02/2026 14:17
Compartilhe
Microsoft Azure Cloud Native 2026Recomendados para vocêMicrosoft Azure Cloud Native 2026

Garbage Collector em Java: Entendendo de vez como a JVM gerencia memória

    O garbage collector de Java é um mecanismo de gerenciamento de memória automático. Ele elimina a necessidade do programador alocar e desalocar memória manualmente. Ele precisa garantir que a JVM tenha memória alocada disponível para rodar a aplicação, porém, para poder realizar isso muitas coisas complexas acontecem por baixo do capô.

    Primeiro preciso falar sobre o problema do manuseio (alocar e desalocar) manual de memória. Em algumas linguagens como C e C++ o desenvolvedor é responsável por manipular a memória, utilizando funções como malloc/free em C ou operadores new/delete em C++. Esse controle total permite alta performance, porém traz riscos como vazamento de memória (memory leaks) e ponteiros pendentes.

    No Java, para contornar essa necessidade, existe o GC (Garbage Collector), que faz todo esse gerenciamento automaticamente, prevenindo memory leaks e aumentando a produtividade e segurança do código com alocação dinâmica e eficiente.

    Beleza, mas como o GC faz para cuidar disso sozinho?

    Vamos aprofundar um pouco.

    Java tem duas principais áreas de memória para armazenar diferentes tipos de dados durante a execução do programa (disse principais porque não são as únicas), temos a memória stack e a heap. Para falar do garbage collector eu vou focar na heap, mas se quiser entender melhor como funcionam essas memórias eu escrevi sobre elas lá no Java Core Notes - Stack e Heap em Java: entendendo memória além do "funciona". Vale a pena conferir.

    Mas vamos lá. Sempre que você cria um objeto em Java, esse objeto é alocado no heap. Ou seja, ele ocupa um espaço de memória no heap (memória que não é infinita).

    Enquanto existir uma referência para esse objeto ( uma variável na stack que aponte para esse objeto) dizemos que ele “vive” no heap. Mas quando um objeto perde sua referência ele é classificado para ser eliminado pelo GC.

    Não faz sentido manter uma estrutura que perdeu referência ocupando a memória, então por meio de verificações periódicas o GC passa verificando os objetos que perderam referência e então libera essa memória para ser utilizada novamente por um novo objeto. Isso previne que o heap fique cheio causando uma OutOfMemoryError.

    Mas como o GC sabe se um objeto está referenciado ou não?

    Já ouviu falar das GC Roots? São referências iniciais que o GC usa para identificar quais objetos na memória ainda tem referência (“vivos”). Tudo que não for alcançável a partir dessas raízes vai ser considerado lixo, e será coletado. Os principais tipos de roots são:

    • variáveis locais na stack
    • parâmetros de métodos
    • campos estáticos
    • JNI references
    • Threads ativas

    Falando superficialmente o GC vai fazer essas verificações de tempos em tempos, coletando os objetos para ajudar manter o heap “saudável”.

    Áreas do heap

    Para ter uma eficiência melhor, o heap é dividido principalmente em duas áreas:

    Young Generation (Eden, Survivor S0/S1) para novos objetos, e Old Generation para os objetos mais velhos. Vou falar mais profundamente dessas áreas em outra postagem, mas entenda que todo objeto nasce em Young-generation( no Éden mais especificamente), se eles viverem tempo suficiente vão para Old-Generation.

    A maioria dos objetos morrem jovens, sabia? (hipótese geracional), e a JVM usa essa característica para dividir o heap nessas duas áreas. Sabendo disso faz sentido o GC trabalhar com mais frequência na Young-generation. Como a maioria dos objetos lá vão ter vida curta, a coleta de lixo aqui é mais rápida e eficiente.

    Objetos que sobrevivem a múltiplos ciclos na geração jovem serão promovidos para a Old-generation onde a coleta é mais lenta, mais rara e mais cara! - aqui acontecem muitos erros por design de código ruim.

    Minor GC e Full GC

    Minor GC é a coleta que ocorre exclusivamente em Young Generation, ela acontece com frequência mais alta.

    Full GC é a coleta que acontece na memória heap inteira, tanto na Young Generation quanto na Old Generation. Ocorre com muito menos frequência (Geralmente quando Old está cheia ou quase cheia). Remove os objetos que sobreviveram a múltiplos ciclos e foram promovidos para a Old Generation. Realiza desfragmentação de memória para otimizar o espaço. Full GC frequente é sinal de problema!

    Durante a coleta, a JVM pode pausar todas as threads da aplicação para garantir consistência da análise de alcance (Stop-The-World). Em aplicações de baixa latência isso pode causar picos de resposta perceptíveis.

    Coletores de GC

    Existem alguns tipos de coletores , cada um com uma característica e prioridade específica. Pretendo falar sobre coletores de GC em outra postagem, mas aqui vai seus nomes:

    • Serial GC - o mais simples
    • Parallel GC - foco em throughput
    • G1 GC - Garbage first - o padrão atual
    • ZGC - baixa latência extrema

    GC aumenta produtividade, mas não elimina problemas de design. Estruturas que mantêm referências desnecessárias ainda causam retenção de memória mesmo com GC.

    Espero que tenham gostado, Qualquer coisa que possa ser relevante sobre o GC comentem ai!

    Esse é mais um conteúdo para o Java Core Notes - um repositório onde anoto tudo sobre meus estudos Java

    https://github.com/ThiagoWill19/java-core-notes

    Compartilhe
    Recomendados para você
    Riachuelo - Cibersegurança
    Microsoft Certification Challenge #5 - AZ-204
    Microsoft Certification Challenge #5 - DP 100
    Comentários (0)
    Recomendados para vocêMicrosoft Azure Cloud Native 2026