Compartilhamento de tecnologia

[Noções básicas de JVM] Introdução ao Java Garbage Collector

2024-07-11

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Coletor de lixo (implementação do algoritmo de coleta de lixo)

O coletor de lixo é a implementação específica do algoritmo de coleta de lixo . Como o coletor de lixo é dividido em geração jovem e geração antiga, além do G1 (que pode controlar tanto a geração nova quanto a geração antiga),Os coletores de lixo de nova e antiga geração devem ser utilizados em pares de acordo com as exigências do hotspot.(Você precisa escolher a combinação correspondente de acordo com a versão do JDK)

A relação de combinação específica é a seguinte:

Insira a descrição da imagem aqui

No código-fonte subjacente da JVM, em alguns casos especiais, o reciclador CMS chamará o reciclador Serial Old.

Arthas visualizar o coletor de lixo utilizado

Você não pode ver diretamente qual coletor de lixo é usado, só pode inferir com base no algoritmo.

Insira a descrição da imagem aqui

Coletor de lixo em série da geração jovem

Série é umColeção serial de thread único da geração jovemO coletor de lixo.

Insira a descrição da imagem aqui

Reciclando idades e algoritmos

  • geração jovem
  • Algoritmo de replicação

vantagem

Excelente rendimento em um único processador CPU

deficiência

A taxa de transferência em múltiplas CPUs não é tão boa quanto em outros coletores de lixo (thread único, usando apenas uma CPU. Se o heap for muito grande, o thread do usuário ficará esperando por um longo tempo).

Cena aplicável

Programas clientes escritos em Java ou cenários com configuração de hardware limitada (poucos núcleos de CPU)

Como usar

-XX: UseSerialGC: Tanto a nova geração quanto a antiga usam o coletor serial.

Coletor de lixo SerialOld de geração antiga

SerialOld é a versão da geração antiga do coletor de lixo Serial, usandoColeta serial de thread único

Insira a descrição da imagem aqui

Reciclando idades e algoritmos

  • velhice
  • Algoritmo de agrupamento de marcas

vantagem

Excelente rendimento em um único processador CPU

deficiência

A taxa de transferência em várias CPUs não é tão boa quanto em outros coletores de lixo. Se o heap for muito grande, o thread do usuário ficará esperando por um longo tempo.

Cena aplicável

Usado com o coletor de lixo serial ou em casos especiais do CMS

Como usar

-XX: UseSerialGC: Tanto a nova geração quanto a antiga usam o coletor serial.

Geração jovem-ParNovo coletor de lixo

O coletor de lixo ParNew é essencialmenteOtimização de serial em múltiplas CPUs, usando multi-threading para coleta de lixo

Insira a descrição da imagem aqui

Idade e algoritmo de reciclagem:

  • geração jovem
  • Algoritmo de replicação

vantagem

  • Tempos de pausa mais curtos em processadores com múltiplas CPUs

deficiência

  • A taxa de transferência e o tempo de pausa não são tão bons quanto G1, portanto não é recomendado após JDK9

Cena aplicável

  • No JDK8 e em versões anteriores, ele é usado em conjunto com o coletor de lixo de geração antiga do CMS.

Como usar

  • -XX: UseParNewGC: A nova geração usa o coletor ParNew e a geração antiga usa o coletor serial.

Insira a descrição da imagem aqui

Coletor de lixo CMS (Concurrent Mark Sweep) de geração antiga

O coletor de lixo CMS concentra-se no tempo de pausa do sistema (para minimizar STW e otimizar a experiência do usuário),Permitir que threads de usuário e threads de coleta de lixo sejam executados simultaneamente em determinadas etapas, reduzindo o tempo de espera dos threads do usuário.

Reciclando idades e algoritmos

  • velhice
  • Algoritmo de marcação e varredura

vantagem

  • O tempo de pausa do sistema devido à coleta de lixo é menor e a experiência do usuário é melhor.

deficiência

1. Problema de fragmentação de memória

2. Problema de degradação (em alguns casos específicos, degenerará em um coletor de thread único, como SerialOld)

3. Problema do lixo flutuante (algum lixo não pode ser reciclado durante o processo de reciclagem)

Cena aplicável

Cenários em sistemas de Internet de larga escala onde os usuários solicitam grandes quantidades de dados e alta frequência, como interfaces de pedidos, interfaces de produtos, etc.

usar

XX: UseConcMarkSweepGC, você pode definir os colecionadores da geração mais jovem e da geração mais velha, respectivamente.

Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

Etapas de execução do CMS

  1. Marcação inicial, marcação em muito pouco tempoObjetos com os quais o GC Roots pode se relacionar diretamente
  2. marcação simultânea, Marcar todos os objetos , o thread do usuário não precisa ser pausado. (Embora a marcação simultânea seja executada junto com o thread do usuário, se os recursos ocupados pela marcação simultânea forem altos, isso também afetará o thread do usuário)
  3. Remarcação (simultaneidade), porque alguns objetos serão alterados durante a fase de marcação simultânea, haverá rotulagem incorreta (o objeto usado estava originalmente ativo, mas após a marcação, o thread do usuário o tornou inviável, resultando em rotulagem incorreta), rotulagem ausente (Porque é simultâneo, alguns objetos podem ter acabado de ser criados pelo thread do usuário, o que levará à falta de tags) e outras situações, e precisam ser remarcados.
  4. Limpeza simultânea, limpeza de objetos mortos, threads de usuário não precisam ser pausados.

Nota: STW só aparecerá durante as fases de marcação inicial e remarcação.

Insira a descrição da imagem aqui

deficiência:

1. O CMS usa um algoritmo de marcação e limpeza Após a conclusão da coleta de lixo, um grande número de fragmentos de memória aparecerá para não afetar a alocação de objetos.O CMS será desfragmentado durante o Full GC. . Isso fará com que o thread do usuário seja pausado,Você pode usar o parâmetro -XX:CMSFullGCsBeforeCompaction=N (padrão 0) para ajustar o GC completo N vezes antes de classificá-lo.

2. Incapaz de lidar com o "lixo flutuante" gerado durante o processo de limpeza simultânea e não pode obter a coleta de lixo completa (durante esse processo de limpeza, o thread do usuário criou alguns objetos simultaneamente, mas eles não foram usados ​​novamente em breve. Esses objetos não são reciclado nesta limpeza e precisa esperar até a próxima limpeza, por isso é chamado de lixo flutuante).

3. Se não houver memória suficiente na geração antiga para alocar objetos, o CMS degenerará em Serial Old single-thread reciclando a geração antiga.

Número de threads simultâneos:

O número de threads ao executar a fase simultânea no CMS pode ser passado-XX:ConcGCThreadsConfiguração de parâmetros, calculada pelo sistema, a fórmula de cálculo é(-XX:ParallelGCThreads定义的线程数 3) / 4, ParallelGCThreads é o número de threads paralelos após a pausa do STW

ParallelGCThreads é determinado pelo número de núcleos do processador:

1. Quando o número de núcleos de CPU é menor que 8, ParallelGCThreads = Número de núcleos de CPU

2. Caso contrário, ParallelGCThreads = 8 (Número de núcleos de CPU – 8)*5/8

Existem 12 processadores lógicos no meu computador, então ParallelGCThreads = 8 (12 - 8) * 5/8 = 10, ConcGCThreads = (-XX: O número de threads definidos por ParallelGCThreads 3) / 4 = (10 3) / 4 = 3

Insira a descrição da imagem aqui

Finalmente você pode obter esta foto:

Insira a descrição da imagem aqui

As fases simultâneas de marcação e limpeza simultâneas serão processadas em paralelo usando três threads. A fase de remarcação será processada usando 10 threads. Como o número de núcleos da CPU é limitado, a fase simultânea afetará o desempenho da execução do thread do usuário.

Insira a descrição da imagem aqui

Coletor de lixo paralelo de geração jovem

Limpeza Paralela éColetor de lixo padrão da geração jovem JDK8, MultithreadingColeção paralelaConcentre-se no rendimento do sistema .Para aumentar o rendimento, o PS iráAjustar automaticamente o tamanho da memória heap (ajustar o tamanho da memória da nova geração, da antiga geração, limite de promoção)

Insira a descrição da imagem aqui

Reciclando idades e algoritmos

  • geração jovem
  • Algoritmo de replicação

vantagem

  • O rendimento é alto e suporta configuração manual de parâmetros para controlar o rendimento. Para melhorar o rendimento, a máquina virtual ajusta dinamicamente os parâmetros do heap (o usuário só precisa definir o rendimento e não precisa definir outros parâmetros, como tamanho da memória).

deficiência

  • Não há garantia de um único tempo de pausa, mas suporta a configuração do tempo STW.

Cena aplicável

  • As tarefas em segundo plano não requerem interação do usuário e tendem a gerar um grande número de objetos.Por exemplo: processamento de big data, exportação de arquivos grandes

Parâmetros comuns

O Parallel Scavenge permite a configuração manual dos tempos máximos de pausa e da taxa de transferência. Os funcionários da Oracle recomendam não definir a memória heap máxima ao usar esta combinação. O coletor de lixo ajustará automaticamente o tamanho da memória com base no tempo máximo de pausa e na taxa de transferência.

  • tempo máximo de pausa,-XX:MaxGCPauseMillis=n Defina o máximo de milissegundos de pausa para cada coleta de lixo
  • Taxa de transferência,-XX:GCTimeRatio=n Defina a taxa de transferência como n (tempo de execução do thread do usuário = n/(n 1))
  • Ajustar automaticamente o tamanho da memória, -XX: UseAdaptiveSizePolicyA configuração permite que o coletor de lixo ajuste automaticamente o tamanho da memória com base na taxa de transferência e nos milissegundos máximos de pausa. Este parâmetro é habilitado por padrão (a Oracle recomenda que, ao usar a combinação PS, não defina o valor máximo da memória heap e deixe o coletor de lixo ajustar automaticamente. )

Nota: Os dois indicadores de tempo máximo de pausa e taxa de transferência estão em conflito. O coletor de lixo fará o possível para atender ao tempo máximo de pausa (às vezes ele é definido como muito pequeno e não pode ser atendido, e o tempo máximo de pausa definido será excedido). , sacrificando a produtividade.Se você quiser definir o tempo máximo de pausa e a taxa de transferência ao mesmo tempo, precisará fazer mais testes para torná-los mais coordenados.

Coletor de lixo antigo paralelo de geração antiga

Parallel Old é uma versão de geração antiga projetada para o coletor Parallel Scavenge, utilizando coleção simultânea multithread.

Insira a descrição da imagem aqui

Reciclando idades e algoritmos

  • velhice
  • Algoritmo de agrupamento de marcas (na verdade, classificação de limpeza de marcas)

vantagem

  • A coleta simultânea é mais eficiente em CPUs multi-core

deficiência

  • O tempo de pausa será maior

Cena aplicável

  • Usado com limpeza paralela

Como usar

JDK8 define parâmetros para usar este reciclador por padrão.

parâmetro:-XX: UseParallelGC ou-XX: UseParallelOldGCVocê pode usar a combinação Parallel Scavenge Parallel Old.
Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

teste

-XX: PrintFlagsFinal: Você pode imprimir os valores finais de todos os itens de configuração quando o programa for iniciado. Você pode verificar se a função de ajuste automático está ativada.

Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 垃圾回收器案例3
 */
//-XX: UseSerialGC -Xmn1g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc -XX: PrintFlagsFinal
//-XX: UseParNewGC  -Xmn1g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc
//-XX: UseConcMarkSweepGC
//-XX: UseG1GC   -Xmn8g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc MaxGCPauseMillis
//-XX: PrintFlagsFinal  -XX:GCTimeRatio = 19  -XX:MaxGCPauseMillis=10 -XX: UseAdaptiveSizePolicy
public class GcDemo2 {

    public static void main(String[] args) throws IOException {
        int count = 0;
        List