Vários coletores de lixo comumente usados --- Java virtual machine (texto de 5.000 palavras, altamente recomendado)


1. Introdução

Apresentei vários algoritmos para determinar se um objeto está "morto" e como coletar objetos de "lixo". Agora devemos dar uma olhada em vários coletores de lixo clássicos que os colocam em prática.

O que é explicado aqui é que o coletor de lixo é dividido em

  • Minor GC (para a nova geração): Serial, ParNew, Parallel Scavenge
  • Principal GC (para idosos): CMS (Simultâneo Mark Sweep) , Serial Antigo, Paralelo Antigo
  • GC misto: G1 (lixo primeiro)

E eles têm sua própria combinação, e o diagrama de combinação é o seguinte:

Insira a descrição da imagem aqui

Mas a combinação de Serial + CMS e ParNew + Serial Old foi abandonada no JDK 9. CMS e G1 são os pontos-chave do nosso entendimento.

Posteriormente, ouviremos sobre os coletores "simultâneos" e "paralelos". Aqui, "simultaneidade" e "paralelo" podem ser entendidos como no contexto da discussão dos coletores de lixo:

  • Paralelo (Paralelo): Paralelo descreve a relação entre vários encadeamentos do coletor de lixo, indicando que existem vários encadeamentos trabalhando juntos ao mesmo tempo e, geralmente, o encadeamento do usuário neste momento está em um estado de espera por padrão. JVM Apenas o coletor de lixo está funcionando, o que significa "Parar o mundo" para o usuário.
  • Simultâneo: a simultaneidade aqui descreve a relação entre o coletor de lixo e o encadeamento do usuário. Isso significa que o encadeamento do usuário e o encadeamento do coletor estão trabalhando ao mesmo tempo. Como o encadeamento do usuário ainda está em execução, o programa ainda pode responder às solicitações de serviço No entanto, o encadeamento do coletor de lixo ocupa uma certa quantidade de recursos do sistema, portanto, o rendimento do aplicativo será afetado até certo ponto.

Métricas para medir GC

Existem três indicadores para medir a qualidade de um GC: pegada de memória (pegada) , taxa de transferência (taxa de transferência) e latência (latência) . Esses três constituem um triângulo impossível. O desempenho geral dos três é bom, pois o progresso da tecnologia ficará melhor e melhor. Mas é impossível atingir quase a perfeição em todos os três aspectos. Um bom GC geralmente só pode atingir dois deles ao mesmo tempo.

  • Pegada de memória: o tamanho do espaço de memória que o encadeamento GC ocupará quando estiver em execução
  • Taxa de transferência: a proporção de tempo que o processador gasta executando o código do usuário em relação ao tempo total do processador. Se expresso por uma fórmula, é: tempo de execução do código do usuário / (tempo de execução do código do usuário + tempo de coleta de lixo em execução)
  • Atraso: O atraso ocorre porque o thread do usuário deve ser suspenso por um período de tempo (Stop The World) durante o processo de GC. O tempo durante o qual o thread do usuário é suspenso é o atraso.

Mas a importância do atraso é cada vez mais reconhecida por todos . Porque com o aprimoramento e o progresso do hardware do computador, podemos tolerar cada vez mais o GC ocupando um pouco mais de espaço. Também podemos aceitar sacrificar uma certa quantidade de eficiência (rendimento ) em troca de uma melhor experiência do usuário. Para ser franco, o uso de memória e a taxa de transferência podem ser resolvidos gastando dinheiro em hardware. Além disso, a Internet é um setor de serviços até certo ponto e precisa agradar aos usuários. Os usuários não Seu servidor não é eficiente, ele só se preocupa com a experiência do usuário que este site traz para ele.E a latência é uma experiência de usuário muito importante.

2. Minor GC (GC de nova geração)

Os seguintes tipos de Minor GC são baseados no algoritmo de marcação e cópia.

  • GC serial (o GC secundário mais antigo e básico)
  • ParNew GC (foco na redução do tempo de resposta)
  • Eliminação paralela (foco em melhorar o rendimento)

1. GC Serial (GC Menor)

O GC serial é o GC mais básico e mais antigo. Antes de JDK1.3, ele era a única escolha para a nova geração de GC de máquina virtual. Serial é um coletor de thread único. Aqui, thread único tem dois significados:

  1. serial usará apenas um tópico de coleção
  2. Quando o serial está realizando a coleta de lixo, outros threads de trabalho devem suspender todo o trabalho em andamento até que o serial conclua a coleta de lixo. Isso é "Stop The World".

Diagrama de operação serial / serial antigo do GC:

Insira a descrição da imagem aqui

Pode-se esperar que "Stop The World" seja uma experiência terrível para os usuários. Imagine que, quando você está assistindo a um vídeo, de repente o reprodutor de vídeo para de reproduzir imediatamente. Você não pode realizar nenhuma operação no computador porque Serial está sendo executado GC. Na verdade, é porque traz uma experiência ruim para os usuários. Desde o JDK1.3 até o JDK14 atual, a equipe de desenvolvimento da máquina virtual HotSpot tem se esforçado muito para reduzir esse "Stop The World".

Mas isso não significa que o SerialGC seja o primeiro a aparecer e não tenha nenhum efeito no momento. Na verdade, ainda é o padrão mais recente da máquina virtual HotSpot no ** lado do cliente (mas o campo principal do Java é o lado do servidor) * * Geração de GC. Para computadores com menos núcleos e recursos de memória limitados, porque não há sobrecarga de interação de encadeamento, o Serial que se concentra no GC pode alcançar maior eficiência.

2.ParNew GC (Minor GC)

ParNewGC pode, na verdade, ser considerado uma versão paralela de vários threads de SerialGC . Exceto pelo uso de vários threads para coleta de lixo ao mesmo tempo. Não há muita diferença entre ParNew e Serial. Embora não pareça ter nenhum ponto brilhante , mas antes do JDK7, é a primeira escolha de muitas máquinas virtuais do lado do servidor para a nova geração de GC. Mas o engraçado é que se tornou a escolha de muitas pessoas não por causa de si mesmas, mas por causa da liderança ( CMS). Apresentaremos o CMS mais tarde.

Diagrama esquemático ParNewGC:

Insira a descrição da imagem aqui

Antes do lançamento do G1, pode-se dizer que o CMS é o GC mais adequado da velha geração no lado do servidor, e o GC da nova geração que pode ser combinado com ele é apenas Serial e ParNew. A eliminação paralela não pode ser combinada com o CMS para alguns Mas depois com o surgimento do G1, ele substituiu gradativamente o CMS.

3. Eliminação paralela (GC menor)

Parallel Scavenge também é um GC de nova geração. Parallel Scavenge e ParNew GC são semelhantes em muitos recursos na superfície, mas o ponto mais importante é que eles se concentram em níveis diferentes. Coletores como ParNew e CMS se concentram principalmente no encurtamento. Tempo de pausa , e Parallel Scavenge e seu antigo GC-Parallel Old GC correspondente focam em melhorar o rendimento ... O diagrama esquemático do Parallel Scave GC será dado junto com o seguinte Parallel Old GC

3. Maior GC (antigo GC)

Os seguintes GCs principais são baseados no algoritmo de cópia de marcação, exceto que o CMS usa o algoritmo de varredura de marcação.

  • Paralelo Antigo
  • Serial Antigo
  • CMS

1 GC antigo paralelo

Parallel Old GC é a versão antiga do Parallel Scavenge e também oferece suporte à coleta paralela multithread. Em cenários onde a taxa de transferência é importante, a combinação de Parallel Scavenge + Parallel Old é frequentemente usada. Parallel Old + Parallel Scavenge são usados ​​juntos:

Insira a descrição da imagem aqui

2. Serial Antigo

Serial Old é a versão antiga do Serial GC. Suas funções são principalmente em dois aspectos:

  • Antes do surgimento do Parallel Old, era usado como a velhice do Parallel Scavenge
  • Como alternativa, após o erro de Falha de modo simultâneo no coletor CMS.

3.CMS (varredura de marca simultânea) foco !!!

CMS GC é um coletor que visa obter o menor tempo de pausa de recuperação. As páginas atuais da Internet prestam grande atenção à velocidade de resposta da página da Web para melhorar a experiência interativa do usuário. Assim, o CMS atende perfeitamente às necessidades de tais aplicativos. Portanto, é muito Por muito tempo, foi a primeira escolha para o antigo GC no lado do servidor (até o surgimento do G1).

E pelo seu nome, pode-se ver que é concorrente e se baseia no algoritmo de varredura de marca.Vamos dar uma olhada no CMS.

3.1 Processo de implementação de CMS

Insira a descrição da imagem aqui

  1. Marca inicial
  2. Marca concorrente
  3. Observação
  4. Varredura simultânea

Em primeiro lugar, pode ser visto a partir do diagrama esquemático e do nome que o thread do usuário não precisa ser interrompido na marcação simultânea e fase de limpeza simultânea. O thread do usuário "Stop The World" deve ser interrompido durante a marcação e remarcação inicial .

A primeira etapa (marcação inicial): A etapa inicial serve apenas para marcar os objetos que o GC Roots pode associar diretamente, embora o thread do usuário seja suspenso nesta etapa, a velocidade é muito rápida.

O segundo estágio (marca de simultaneidade): este estágio é o processo de percorrer todo o gráfico do objeto a partir dos objetos diretamente associados ao GC Roots. Este estágio leva muito tempo e consome certos recursos do sistema. No entanto, o thread do usuário ainda será executado normalmente .

O terceiro estágio (remarcação): Como a marcação simultânea é executada simultaneamente com os threads do usuário, este processo irá gerar um novo "lixo" e algum "lixo" não será mais "lixo". A remarcação é para corrigir o processo simultâneo geração Este processo será um pouco mais longo que o estágio inicial, mas ainda é relativamente curto.

O quarto estágio (limpeza simultânea): Este estágio é para limpar objetos que foram marcados como "mortos". Uma vez que o algoritmo de limpeza de marcas não precisa mover objetos, este processo pode ser executado simultaneamente com threads do usuário.

3.2 Desvantagens óbvias do CMS

O CMS é um excelente GC. Suas principais vantagens podem ser vistas pelo nome. Mas ainda tem desvantagens óbvias:

  1. O CMS é muito sensível aos recursos do processador. Na verdade, os programas orientados à simultaneidade são muito sensíveis aos recursos do processador. No estágio de simultaneidade, embora não pause o thread do usuário, ele fará com que o thread do usuário seja executado lentamente porque ocupa o sistema recursos. Reduzir o rendimento total. Mas, para ser honesto, no nível de hardware moderno de hoje, isso não é tão importante.
  2. O CMS não pode lidar com lixo flutuante (Floating Garbage) , o que leva a um GC Completo "Stop The World" completo. Na fase de limpeza simultânea, o thread do usuário ainda está em execução e gerando novos objetos de lixo. E esse objeto de lixo não pode estar neste Eliminado em etapas. Esses objetos de lixo são chamados de lixo flutuante. Esses objetos de lixo flutuantes aparecem após a fase de limpeza simultânea. Eles só podem ser removidos até o próximo GC.
  3. O CMS corre o risco de "Falha no modo simultâneo". Também é porque os threads do usuário ainda estão em execução ao mesmo tempo durante a fase de coleta de lixo, então você precisa reservar espaço para os threads do usuário. Mas se for um GC paralelo, apenas o GC está em execução durante o GC, então você pode esperar até que a área para idosos esteja quase cheia antes de executar. Mas o CMS simultâneo não pode. Quanto espaço deve ser reservado para os tópicos do usuário? Isso é um problema. Se o espaço reservado for não o suficiente para que os encadeamentos do usuário sejam executados, apenas Haverá "Falha no modo simultâneo". Neste momento, a JVM terá que iniciar uma solução alternativa: congelar encadeamentos do usuário e ativar temporariamente o Serial Antigo para executar a coleta de lixo na geração anterior. causará uma pausa mais longa.
  4. As deficiências do próprio algoritmo de varredura de marcação. Eu também apresentei isso no artigo correspondente, ou seja, o algoritmo de varredura de marcação causará uma grande quantidade de fragmentação de memória . Quando a fragmentação de memória afetou a alocação de memória do objeto, ela terá para acionar um GC Completo com antecedência. Para resolver este problema, o JVM pode definir dois parâmetros. O primeiro é: quando FullGC tiver que ser executado, a memória é desfragmentada. O segundo é: após vários GCs serem executados, ele irá ser fragmentado antes da próxima classificação de GC

4.Misturado GC (Mixed GC) superchave !!!

No momento, há apenas G1 (Garbage First) disponível comercialmente GC Mixed . G1 GC é uma conquista marco na história do desenvolvimento de coletores de lixo . G1 foi pioneiro na idéia do projeto de coletores para coleta parcial ea forma de layout de memória com base em Região .

G1 foi criado para ser o substituto e o sucessor de CMS e Parallel Old + Parallel Scavenge. O objetivo oficial definido para G1 é obter a maior taxa de transferência possível com atraso controlável. Torne-se um coletor de recursos completo. ** No JDK9 e em versões mais avançadas, G1 tornou-se o GC padrão. CMS não é mais recomendado.

Como G1 é um GC inovador, naturalmente precisamos entender seu pioneirismo e como ele difere de outros OGs clássicos.

4.1 Lançamento do G1

1. Layout de memória baseado em região : Todos sabem que a memória heap no GC anterior é baseada na teoria geracional. Na verdade, G1 também é baseado na teoria geracional. Mas ele não aloca o espaço na memória heap continuamente. A memória heap é dividida em muitas regiões. Cada região pode ser a velha geração, talvez o Éden, sobrevivente na nova geração. E se a memória de um objeto exceder a metade da região, o objeto será julgado como um grande objeto. Haverá uma área Humongous dedicada ao armazenamento. Se um objeto supergrande exceder toda a região, ele será armazenado em N áreas Humongous consecutivas. Humongous geralmente é tratado como uma idade avançada .

A comparação entre a distribuição de memória da região e a distribuição de memória clássica é a seguinte:

Insira a descrição da imagem aqui

Insira a descrição da imagem aqui

2. Modelo de tempo de pausa previsível (para coleta parcial)

Ao contrário do GC anterior, que é um GC secundário ou um GC principal **, G1 não realiza GC em toda a geração jovem ou velha. Em vez disso, o GC é realizado na unidade da Região **. G1 faz um julgamento de valor para cada Região. O índice de julgamento de valor é principalmente de dois pontos: o tempo necessário para esta coleção e o tamanho do bloco de espaço obtido por esta coleção. E uma lista de prioridades é mantida em segundo plano, e a coleção é processada primeiro de acordo com a coleção permitida tempo de pausa definido pelo usuário. Regiões com maior valor. Essa também é a origem do nome Garbage First. Este método de coleta parcial garante que o coletor G1 obtenha a maior eficiência de coleta possível em um tempo limitado. Mas isso precisa ser explicado : o usuário irá definir um tempo de pausa, mas o GC pode não estar necessariamente dentro deste tempo, mas vai tentar fazê-lo.

4.2 Processo de execução G1

  1. Marcação Inicial
  2. Marcação Simultânea
  3. Marcação Final
  4. Filtro claro (contagem e evacuação de dados ao vivo)

Entre eles, TAMS e SATB serão introduzidos posteriormente.

Estágio de marcação inicial : neste estágio, o GC marca apenas os objetos aos quais o GC Roots pode se associar diretamente. E modifica o TAM (Top at Mark Start será apresentado mais tarde) . Quando o próximo estágio de marcação simultânea, os objetos podem ser alocados corretamente em a região. Este estágio precisa interromper o thread do usuário "Stop The World". Mas o tempo é muito curto

Fase de marcação simultânea : esta fase analisará a acessibilidade de objetos no heap de GC Roots para descobrir os objetos a serem reciclados. Demora muito, mas pode ser executado simultaneamente. Isso é semelhante ao CMS, mas classificará SATB (instantâneo original) objetos gravados cujas referências mudam durante a simultaneidade

Fase final de marcação : uma pequena pausa é feita no thread do usuário, que é usada para processar um pequeno número de registros SATB que ainda restam após a fase de marcação simultânea.

Etapa de triagem e limpeza : Responsável por atualizar o valor da Região e, em seguida, realizar uma triagem e formular um cronograma de acordo com o tempo de pausa esperado pelo usuário. Por fim, os objetos da Região coletada são copiados para a Região vazia, e os objetos em toda a região antiga são limpos Esta etapa envolve a movimentação de objetos vivos e é executada em paralelo por várias threads, portanto, a thread do usuário deve ser suspensa.

Percebe-se que além da fase de marcação concorrente, o coletor G1 precisa suspender o thread do usuário nas demais fases, o que é determinado por G1 não apenas em busca do tempo de resposta.

De um ponto de vista geral, G1 utiliza um algoritmo de organização de marcas, mas de um ponto de vista parcial (entre duas regiões), utiliza um algoritmo de cópia de marcas, não havendo fragmentação da memória .

5. Detalhes da análise de acessibilidade simultânea

Você pode descobrir que a fase de marcação nos coletores CMS e G1 é simultânea, o que é diferente do GC anterior, então por que pode ser simultânea na fase de marcação? Os threads do usuário também estão em execução ao mesmo tempo durante este período. A referência a relação pode mudar durante o período. Isso pode causar dois problemas:

  1. Acontece que o objeto que deveria morrer é julgado como vivo , o que irá gerar lixo flutuante, mas isso não é um grande problema e é aceitável. Não há problema em reciclá-lo no próximo GC
  2. Acontece que o objeto que deveria sobreviver é julgado como morto . Esse é um grande problema que fará com que o programa trave. Precisamos resolvê-lo.

Este é o problema de consistência . Abaixo podemos usar a marca de três cores para demonstrar o processo de marcação. A marca de três cores marca o objeto em três cores de acordo com a condição "foi visitado":

  1. Branco: indica que o objeto não foi visitado pelo GC. Todos os objetos são brancos no estágio inicial. Se ainda houver objetos que são brancos no estágio final, então é inacessível.
  2. Cinza: indica que o próprio objeto foi visitado, mas suas referências a outros objetos não foram completamente verificadas.
  3. Preto: indica que o objeto foi acessado pelo GC e suas referências a outros objetos também foram completamente verificadas.

Se a marca de três cores for usada para demonstrar o processo de digitalização, é equivalente a um processo gradual do preto ao cinza e ao branco.

Insira a descrição da imagem aqui

Os pesquisadores descobriram que o problema do "desaparecimento do objeto" ocorre quando e somente quando duas condições são atendidas ao mesmo tempo.

  1. O avaliador remove todas as referências diretas ou indiretas do objeto cinza para o objeto branco.
  2. O avaliador inseriu uma ou mais novas referências do objeto preto para o objeto branco.

Portanto, para evitar o problema do "desaparecimento do objeto", precisamos apenas destruir uma das duas condições. Isso leva a duas soluções:

  1. Instantâneo no início : G1 usa este esquema. O instantâneo original destrói a primeira condição: quando o objeto cinza deseja excluir a relação de referência com o objeto branco, a referência a ser excluída é registrada. Após a marca de simultaneidade terminar, o cinza os objetos das referências nesses registros são tomados como raízes e verificados novamente.
  2. Atualização incremental : o CMS usa este esquema. A atualização incremental destrói a segunda condição: quando um objeto preto insere um novo ponteiro para um objeto branco, isso é registrado e aguardado até o final da marca simultânea. Em seguida, verifique o objeto preto no registro novamente

6 Comparação de G1 e CMS

Como uma escolha popular para GC do lado do servidor, o G1 será inevitavelmente comparado com o CMS anterior. Algumas pessoas pensam que é necessário comparar o G1 com o CMS, porque o CMS foi oficialmente abandonado. Mas, na verdade, o CMS não foi completamente substituído por G1. Em alguns cenários específicos, o desempenho de G1 não é tão bom quanto CMS. As diferenças entre eles são as seguintes:

  1. G1 pode atingir maior rendimento enquanto tenta atender o tempo de resposta definido pelo usuário
  2. G1 não irá gerar fragmentação de memória durante a execução. Na verdade, isso ocorre porque o CMS é baseado no algoritmo de remoção de marcas, enquanto G1 é baseado no algoritmo de classificação de marcas como um todo e parcialmente baseado no algoritmo de cópia de marcas.
  3. O CMS usa um algoritmo de atualização incremental (Atualização Incremental) para resolver o problema de consistência na fase de marcação simultânea , enquanto G1 usa o instantâneo original (Instantâneo no STAB inicial) .
  4. O uso de memória e a carga de execução de G1 no processo de execução são maiores do que o de CMS. O uso de memória é maior (cerca de 10% -20% a mais) porque cada região de G1 tem um conjunto lembrado (conjunto de memória), e a execução A carga é maior. A alta é que eles usam barreiras de gravação para manter o Conjunto Lembrado, mas como o Conjunto Lembrado de G1 é mais complexo, ele irá gerar mais carga.
  5. O G1 usa os algoritmos e ideias mais recentes e pioneiros. Portanto, ainda há muito espaço para melhorias e dividendos. Por outro lado, o suporte da Oracle para o G1 não pode ser ignorado.

Em resumo: em um ambiente com pouca memória e recursos de sistema insuficientes, o efeito do uso de CMS pode ser melhor. Ao contrário, G1 é uma escolha melhor. De modo geral, este ponto crítico é (heap A memória está entre 6-8 G) .

Acho que você gosta

Origin blog.csdn.net/qq_44823898/article/details/110007459
Recomendado
Clasificación