minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
O formato de configuração de parâmetros JVM do programa Spring Boot (a inicialização do Tomcat é adicionada diretamente ao arquivo catalina.sh no diretório bin):
java -Xms2048M -Xmx2048M -Xmn1024M -Xss512K -XX:Tamanho do Metaspace=256M -XX:Tamanho Máximo do Metaspace=256M -jar microservice-eureka-server.jar
para concluir:
Quanto menor a configuração -Xss, menor o valor de contagem, o que significa que menos quadros de pilha podem ser alocados em uma pilha de encadeamentos, mas o número de encadeamentos que podem ser abertos será maior para a JVM como um todo.
-Xss: tamanho da pilha de cada thread, padrão 1M
-Xms: Defina o tamanho inicial disponível do heap, o padrão é 1/64 da memória física
-Xmx: Defina o tamanho máximo disponível do heap, o padrão é 1/4 da memória física
-Xmn: tamanho da nova geração
-XX:NewRatio: O padrão 2 significa que a nova geração é responsável por 1/2 da geração antiga e 1/3 de toda a memória heap.
-XX:SurvivorRatio: O padrão 8 significa que uma área sobrevivente ocupa 1/8 da memória Eden, ou seja, 1/10 da memória da nova geração.
Existem dois parâmetros JVM sobre metaspace: -XX:MetaspaceSize=N e -XX:MaxMetaspaceSize=N
-XX: MaxMetaspaceSize: Defina o tamanho máximo do metaspace. O padrão é -1, o que significa que não há limite ou é limitado apenas pelo tamanho da memória local.
-XX: MetaspaceSize: Especifique o limite inicial para o metaspace acionar Fullgc (não há tamanho inicial fixo para o metaspace), em bytes. O padrão é cerca de 21M. Quando esse valor for atingido, o gc completo será acionado para o tipo de descarregamento. o coletor ajustará este valor: Se uma grande quantidade de espaço for liberada, reduza o valor adequadamente, se uma pequena quantidade de espaço for liberada, aumente o valor adequadamente sem exceder -XX:MaxMetaspaceSize (se definido). Isso tem um significado diferente do parâmetro -XX:PermSize nas versões anteriores do jdk. -XX:PermSize representa a capacidade inicial da geração permanente.
Como o redimensionamento do metaespaço requer Full GC, esta é uma operação muito cara. Se ocorrer um grande número de Full GC quando o aplicativo for iniciado, geralmente é devido ao redimensionamento da geração permanente ou do metaspace. geralmente recomendado Nos parâmetros JVM, defina MetaspaceSize e MaxMetaspaceSize com o mesmo valor e defina-os maiores que o valor inicial. Para uma máquina com memória física de 8G, geralmente defino ambos os valores para 256M.
Na máquina virtual HotSpot, o layout dos objetos armazenados na memória pode ser dividido em três áreas: cabeçalho do objeto (Header), dados da instância (Instance Data) e preenchimento de alinhamento (Padding). O cabeçalho do objeto da máquina virtual HotSpot inclui duas partes de informações. A primeira parte é usada para armazenar os dados de tempo de execução do próprio objeto, como código hash (HashCode), idade de geração do GC, sinalizador de status de bloqueio, bloqueio mantido pelo thread. , ID de thread tendencioso, carimbos de data/hora favorecidos, etc. A outra parte do cabeçalho do objeto é o ponteiro de tipo, que é o ponteiro do objeto para seus metadados de classe. A máquina virtual usa esse ponteiro para determinar de qual classe o objeto é uma instância.
1. Usar ponteiros de 32 bits (o armazenamento real usa 64 bits) no HotSpot em uma plataforma de 64 bits usará cerca de 1,5 vezes mais memória. Usar ponteiros maiores para mover dados entre a memória principal e o cache ocupa uma largura de banda maior. ao mesmo tempo, a GC também estará sob maior pressão
2. Para reduzir o consumo de memória em plataformas de 64 bits, habilite a função de compactação de ponteiro
3. Em jvm, endereços de 32 bits suportam até 4G de memória (2 elevado à 32ª potência), que pode ser otimizada compactando e codificando o ponteiro do objeto quando ele é armazenado na memória heap e decodificando-o após retirá-lo para o registro da CPU (o ponteiro do objeto está no heap São 32 bits, 35 bits no registro, 2 elevado à 35ª potência = 32G), permitindo que a jvm suporte configurações de memória maiores (menores ou iguais a 32G) usando apenas Endereços de 32 bits
4. Quando a memória heap for menor que 4G, não há necessidade de habilitar a compactação de ponteiro. O jvm removerá diretamente o endereço alto de 32 bits, ou seja, usará o espaço de endereço virtual baixo.
5. Quando a memória heap for maior que 32G, o ponteiro de compactação se tornará inválido e 64 bits (ou seja, 8 bytes) serão forçados a endereçar o objeto Java. Isso causará o problema de 1, portanto, é melhor não ter. a memória heap maior que 32G.
Nesse caso, a JVM pode otimizar o local de alocação de memória do objeto ativando o parâmetro de análise de escape (-XX:+DoEscapeAnalysis), para que ele seja alocado na pilha primeiro por meio de substituição escalar (a alocação na pilha é a análise de Escape). ativado por padrão após JDK7. Se desejar, desligue usando parâmetros (-XX: -DoEscapeAnalysis).
Substituição escalar: Quando é determinado através da análise de escape que o objeto não será acessado externamente e o objeto pode ser decomposto posteriormente, a JVM não criará o objeto, mas decomporá as variáveis de membro do objeto em várias variáveis de membro usadas por este método e substitua-as. Essas variáveis de membro de substituição alocam espaço no quadro de pilha ou no registro, de modo que não haja alocação de memória insuficiente para o objeto porque não há um grande espaço contíguo. Habilite parâmetros de substituição escalar (-XX:+ElimineAllocations), que são habilitados por padrão após JDK7.
Quantidades escalares e agregadas: um escalar é uma quantidade que não pode ser decomposta posteriormente, e o tipo de dados básico de JAVA é um escalar (como int, long e outros tipos de dados básicos e tipos de referência, etc.). é uma quantidade que pode ser posteriormente decomposta, e essa quantidade é chamada de quantidade de polimerização. Em JAVA, os objetos são agregados que podem ser decompostos posteriormente.
Objetos grandes são objetos que requerem uma grande quantidade de espaço de memória contínua (como strings e arrays). Parâmetro JVM -XX:PretenureSizeThreshold pode definir o tamanho de objetos grandes. Se o objeto exceder o tamanho definido, ele entrará diretamente na geração antiga e não entrará na geração mais jovem. Este parâmetro só é válido nos dois coletores Serial e ParNew.
Por exemplo, defina os parâmetros JVM: -XX:PretenureSizeThreshold=1000000 (a unidade é bytes) -XX:+UseSerialGC Se você executar o primeiro programa acima, descobrirá que o objeto grande entra diretamente na geração antiga.
Por que tem que ser assim?
Para evitar operações de cópia ao alocar memória para objetos grandes e reduzir a eficiência.
Na área Survivor onde o objeto está colocado atualmente (uma das áreas, a área s onde o objeto está colocado), o tamanho total de um lote de objetos é maior que 50% do tamanho da memória desta área Survivor (-XX :TargetSurvivorRatio pode ser especificado), então neste momento é maior que Objetos que são iguais à idade máxima deste lote de objetos podem entrar diretamente na velhice. Por exemplo, há um lote de objetos na área Survivor. a soma de vários objetos de idade com idade 1 + idade 2 + idade n excede 50% da área do Sobrevivente. Neste momento, todos os objetos com idade n (inclusive) e acima serão colocados na geração antiga. Na verdade, esta regra espera que os objetos que podem sobreviver por muito tempo entrem na velhice o mais rápido possível. O mecanismo de julgamento de idade dinâmico do objeto geralmente é acionado após gc menor.
Antes de cada gc menor na geração mais jovem, a JVM calculará o espaço livre restante na geração antiga.
Se o espaço disponível for menor que a soma dos tamanhos de todos os objetos existentes na geração mais jovem (incluindo objetos de lixo)
Ele verificará se o parâmetro "-XX:-HandlePromotionFailure" (definido por padrão em jdk1.8) está definido.
Se este parâmetro estiver presente, ele verificará se o tamanho da memória disponível na geração antiga é maior que o tamanho médio dos objetos que entraram na geração antiga após cada gc menor anterior.
Se o resultado da etapa anterior for menor ou os parâmetros mencionados anteriormente não forem definidos, um GC completo será acionado e a geração antiga e a geração mais jovem serão coletadas juntas se ainda não houver espaço suficiente para armazenar a nova. objetos após a reciclagem, ocorrerá "OOM".
Claro, se o tamanho dos objetos sobreviventes restantes que precisam ser movidos para a geração antiga após o gc menor ainda for maior que o espaço disponível na geração antiga, o gc completo também será acionado após o gc completo, se houver. ainda não há espaço para os objetos sobreviventes após o gc menor, também ocorrerá "OOM"
Vários carregadores de classes principais do Tomcat:
commonLoader: o carregador de classes mais básico do Tomcat As classes no caminho de carregamento podem ser acessadas pelo próprio contêiner do Tomcat e por cada Webapp;
catalinaLoader: O carregador de classes privado do contêiner Tomcat. As classes no caminho de carregamento não são visíveis para o Webapp;
sharedLoader: um carregador de classes compartilhado por cada Webapp. As classes no caminho de carregamento são visíveis para todos os Webapps, mas não para o contêiner Tomcat;
WebappClassLoader: o carregador de classe privado de cada Webapp As classes no caminho de carregamento são visíveis apenas para o Webapp atual, como o carregamento de classes relacionadas em um pacote war. Cada aplicativo de pacote war tem seu próprio WebappClassLoader para obter isolamento mútuo, como um pacote war diferente. aplicações. Diferentes versões de molas são introduzidas para que a implementação possa carregar suas respectivas versões de molas;