JVM bom artigo detalhado, coletor de CMS e análise de log de GC e explicação detalhada do problema de posicionamento

Insira a descrição da imagem aqui
Combate coletor CMS

As últimas perguntas da entrevista real para empresas de Internet de primeira linha coletadas em 2020 (todas organizadas em documentos), há muitos produtos secos, incluindo explicações detalhadas sobre netty, spring, thread, spring cloud, etc., também há planos de aprendizagem detalhados, perguntas de entrevista, etc. Sinto que estou na entrevista Esta seção é muito clara: para obter as informações da entrevista, basta: clicar aqui para obter !!! Senha: CSDNInsira a descrição da imagem aqui

O combate real começa, você está pronto?

Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

Código de cenário de negócios simulado:

@RestController
public class IndexController {
    
    
/***
 * 存 big 对象
 * @return
 */
@GetMapping("/put")
public String process() {
    
    
   ArrayList<User> users = queryUsers();
   for (User user:users){
    
    
      //TODO 业务操作
   }
   return "ok";
}
private ArrayList<User> queryUsers() {
    
    
   ArrayList<User> users = new ArrayList<>();
   for (int i = 0; i < 50000; i++) {
    
    
      users.add(new User(i, "java2b"));
   }
   return users;
}
}
public class User {
    
    

   private int id;
   private String name;
   private byte[] data;

   public User(int id, String name) {
    
    
      this.id = id;
      this.name = name;
      data=new byte[1 * 128 * 1024];
   }
}

Informações do coletor de saída:

/***
 * 打印 jvm 信息
 * @return
 */
@GetMapping("/info")
public String info() {
    
    
   List<GarbageCollectorMXBean> garbages = ManagementFactory.getGarbageCollectorMXBeans();
   StringBuilder stringBuilder = new StringBuilder();
   for (GarbageCollectorMXBean garbage : garbages) {
    
    
      stringBuilder.append("垃圾收集器:名称=" + garbage.getName() + ",收集=" + garbage.getCollectionCount() + ",总花费时间="
              + garbage.getCollectionTime());
      // + ",内存区名称=" + Arrays.deepToString(garbage.getMemoryPoolNames()));
      stringBuilder.append("\r\n");
   }
   MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
   MemoryUsage headMemory = memory.getHeapMemoryUsage();
   long MB = 1024 * 1024;
   stringBuilder.append("head 堆:");
   stringBuilder.append("\t 初始(M):" + headMemory.getInit() / MB);
   stringBuilder.append("\t 最大(上限)(M):" + headMemory.getMax() / MB);
   stringBuilder.append("\t 当前(已使用)(M):" + headMemory.getUsed() / MB);
   stringBuilder.append("\t 提交的内存(已申请)(M):" + headMemory.getCommitted() / MB);
   stringBuilder.append("\t 使用率:" + headMemory.getUsed() * 100 / headMemory.getCommitted() + "%");
   return stringBuilder.toString();
}

Gerando pacote jar implantado nos
parâmetros de inicialização do servidor :

 java -Xms256m -Xmx256m -verbose:gc -Xloggc:/root/jvm/gc-cms.log -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintHeapAtGC -XX:HeapDumpPath=/root/jvm/dump.hprof -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCTimeStamps -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -XX:+PrintGCDetails -XX:+UseCMSCompactAtFullCollection -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=6666 -Djava.rmi.server.hostname=192.168.0.31 -jar /root/jvm/jvm-web-0.0.1-SNAPSHOT.jar > catalina.out &

Aqui, precisamos inserir o significado dos parâmetros JVM.

Parâmetros JVM detalhados:

Significado do parâmetro JVM

-XX: -CMSPrecleaningEnabled
não executa a pré-limpeza . Aqueles que passaram em nossos artigos anteriores sabem que o CMS terá um trabalho de pré-limpeza durante o período de marcação e remarcação simultâneas, e essa aprovação tentará em 5 segundos Espere o YGC chegar. Para não perder muito tempo na fase de remarcação posterior para marcar a nova geração de objetos.

-XX: + UseConcMarkSweepGC
Este parâmetro iniciará o coletor CMS. A nova geração padrão é ParNew, você também pode definir Serial como o coletor de nova geração. Este parâmetro é equivalente a -Xconcgc.

-XX: ParallelGCThreads
é um processador paralelo, é claro que você também pode especificar o número de threads. O número padrão de threads simultâneos é: (ParallelGCThreads + 3) / 4).
-XX: ConcGCThreads
ou -XX: ParallelCMSThreads; Além da maneira de definir threads acima, você também pode definir manualmente o número de threads CMS simultâneos por meio de qualquer um desses dois parâmetros

-XX: CMSInitiatingOccupancyFraction
Como o coletor CMS não é exclusivo, o aplicativo ainda está funcionando durante a coleta de lixo, portanto, é necessário deixar memória suficiente para o aplicativo, caso contrário, ele acionará o FGC. E quando o CMS GC é executado? Ele pode ser definido por este parâmetro, que representa a porcentagem de uso de memória da geração anterior. Quando esse limite for atingido, o CMS será executado. O padrão é 68. Se a memória da geração anterior crescer rapidamente, é recomendável diminuir o limite para evitar FGC. Se o crescimento for lento, você pode aumentar o limite para reduzir o número de GCs CMS. Melhore o rendimento.

-XX: + UseCMSCompactAtFullCollection
Como o CMS usa o algoritmo de limpeza de marcas, a fragmentação da memória não pode ser evitada. Este parâmetro especifica uma desfragmentação após cada CMS.

-XX: CMSFullGCsBeforeCompaction Como cada desfragmentação afetará o desempenho, você pode usar este parâmetro para definir quantas vezes o CMS será desfragmentado, que é a compactação da memória.

-XX: + CMSClassUnloadingEnabled
permite a reciclagem de metadados de classe.

-XX: CMSInitiatingPermOccupancyFraction

Quando a taxa de ocupação da área permanente atingir esse percentual, inicie a reciclagem do CMS (desde que -XX: + CMSClassUnloadingEnabled esteja ativado).

-XX: UseCMSInitiatingOccupancyOnly

Indica que a recuperação do CMS só é executada quando o limite é atingido.

XX: CMSWaitDuration = 2000
Como a condição CMS GC é relativamente simples, a JVM tem um encadeamento para varrer a área Antiga regularmente.O intervalo de tempo pode ser especificado por este parâmetro (em milissegundos) e o padrão é 2s.
Parâmetros da ferramenta JVM:
significado do parâmetro JVM


-XX: + PrintGCDateStamps Imprimir registro de data e hora do GC
-XX: + PrintGCDetails Imprimir detalhes do GC
-XX: + PrintGCTimeStamps Imprime o tempo que leva para a coleta de lixo começar a ser executada
-Xloggc: Saída de informações de coleta de lixo para o arquivo especificado
-verbose: gc Print GC log-
XX: + PrintGCApplicationStopedTime Exibir tempo de suspensão do aplicativo causado por gc
XX: + PrintTenuringDistribution log de promoção de
objeto- XX: + HeapDumpOnOutOfMemoryError Arquivo de despejo de saída quando a memória estourar

Insira a descrição da imagem aqui

Efeito inicial:Insira a descrição da imagem aqui

Acesso:Insira a descrição da imagem aqui

Solicitação put: vamos ver o efeito após acessar o método put por meio de http: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
Durante a operação, descobrimos que um grande número de objetos entrou na velhice, acionou o gc total e o cms foi coletando.

A taxa de utilização atingiu 99% e o cms não parou por um momento:Insira a descrição da imagem aqui

Análise de logInsira a descrição da imagem aqui

Log Analysis 1.0 version: Nós extraímos um log para analisar

[GC (falha de alocação) 0K-> 63K (64K), 0,0047147 s] 10258K-> 6780K (46144K), [Metaspace: 3434K-> 3434K (1056768K)], 0,0047613 s] [Vezes: usuário = 0,02 sys = 0,00, real = 0,00 segundos] O registro tem quatro partes:

GC Completo:

Indica que uma coleta de lixo foi realizada. Não há modificação Completa na frente, indicando que este é um GC Secundário. Observe que isso não significa que apenas a nova geração é GC e o STW existente será STW, seja a nova geração ou a antiga.

Falha de alocação:

Isso mostra que a causa do GC desta vez é porque não há espaço suficiente na geração jovem para armazenar novos dados.

10258K-> 6780K (46144K), a unidade é KB

Os três parâmetros são: a capacidade usada da área de memória (aqui, a geração jovem) antes do GC, a capacidade usada da área de memória após o GC e a capacidade total da área de memória.

0,0047613 s :

Tempo de GC gasto nesta área de memória, em segundos

[Vezes: usuário = 0,04 sys = 0,00, real = 0,01 segundos]:

Respectivamente representam o modo de usuário demorado, o modo kernel demorado e total Insira a descrição da imagem aqui

Versão do Log Analysis 2.0:

Usando gceasy online para análise, abrimos o site e carregamos os logs gc que produzimos, conforme mostrado na figura: Insira a descrição da imagem aqui

Problemas de otimização: 4 problemas que podem ser otimizados são listados para o uso de memória de meta-espaço da nova geração e da velha geração Insira a descrição da imagem aqui

Estatísticas de rendimento: 97,39%
Insira a descrição da imagem aqui
das alterações de memória de cada geração
Insira a descrição da imagem aqui

O tempo gasto pelo coletor de lixo CMS em diferentes períodos

Insira a descrição da imagem aqui
Insira a descrição da imagem aqui
Classificação e tempo de ocorrência de GC demorado
Insira a descrição da imagem aqui

Problema de posicionamento

Usamos os arquivos de instantâneo produzidos para localizar o problema: Insira a descrição da imagem aqui
JProfiler:

Baixado para a visualização aberta local por meio do JProfiler Insira a descrição da imagem aqui
View, objetos grandes Insira a descrição da imagem aqui
que encontramos são a coleção ArrayList que ocupa 96% da memória, então damos uma olhada no pedaço de código que faz uso pesado de nossa coleção ArrayList Insira a descrição da imagem aqui
para encontrar os códigos correspondentes Insira a descrição da imagem aqui
pelo código que encontramos método put OOM de estouro de memória causado pelo uso extensivo da coleção ArrayList

Resumindo

Acredito que todos entendam o combate real acima. O processo geral é:

1. O suficiente para simular o cenário real de alto volume do usuário do projeto SpringBoot

2. Configure os parâmetros JVM e, em seguida, implemente os dados de monitoramento em execução para gerar arquivos de log

3. Confirme o problema analisando o arquivo de log.
Amigos que precisam do código e do software acima, também têm planos de estudo detalhados, perguntas de entrevista, etc. Acho que a entrevista é muito clara: para obter apenas as informações da entrevista: clique aqui para obtê-la !!! Senha: CSDN todos podem fazer você mesmo Aprofunde a impressão em operação real.Insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/a3961401/article/details/109407949
Recomendado
Clasificación