1. Por que otimizamos a JVM
No ambiente de desenvolvimento local, raramente encontramos a necessidade de otimizar a JVM, mas no ambiente de produção, podemos ter os seguintes requisitos:
- O aplicativo em execução está "travado", o log não é gerado e o programa não responde
- A carga da CPU do servidor aumenta repentinamente
- Em um aplicativo multithread, como alocar o número de threads?
A versão do JDK usada desta vez é 1.8
Segundo, os parâmetros operacionais da JVM
Há muitos parâmetros que podem ser definidos na jvm, para que a jvm possa ser executada com eficiência em vários ambientes, e a maioria dos parâmetros pode ser mantida por padrão.
2.1 Três tipos de parâmetros
Os tipos de parâmetro da jvm são divididos em três categorias, a saber:
-
Parâmetros padrão
- -Socorro
- -versão
-
Parâmetros -X (parâmetros não padrão)
- -Xint
- -Xcomp
-
Parâmetro -XX (maior taxa de uso)
- -XX: newSize
- -XX: + UseSerialGC
2.2 Parâmetros padrão
Os parâmetros padrão da jvm geralmente são muito estáveis e não serão alterados nas versões futuras da JVM.Você pode usar java -help para recuperar todos os parâmetros padrão
[root@localhost ~]# java -help
用法: java [-options] class [args...]
(执行类)
或 java [-options] -jar jarfile [args...]
(执行 jar 文件)
其中选项包括:
-d32 使用 32 位数据模型 (如果可用)
-d64 使用 64 位数据模型 (如果可用)
-server 选择 "server" VM
默认 VM 是 server.
-cp <目录和 zip/jar 文件的类搜索路径>
-classpath <目录和 zip/jar 文件的类搜索路径>
用 ; 分隔的目录, JAR 档案
和 ZIP 档案列表, 用于搜索类文件。
-D<名称>=<值>
设置系统属性
-verbose:[class|gc|jni]
启用详细输出
-version 输出产品版本并退出
-version:<值>
警告: 此功能已过时, 将在
未来发行版中删除。
需要指定的版本才能运行
-showversion 输出产品版本并继续
-jre-restrict-search | -no-jre-restrict-search
警告: 此功能已过时, 将在
未来发行版中删除。
在版本搜索中包括/排除用户专用 JRE
-? -help 输出此帮助消息
-X 输出非标准选项的帮助
-ea[:<packagename>...|:<classname>]
-enableassertions[:<packagename>...|:<classname>]
按指定的粒度启用断言
-da[:<packagename>...|:<classname>]
-disableassertions[:<packagename>...|:<classname>]
禁用具有指定粒度的断言
-esa | -enablesystemassertions
启用系统断言
-dsa | -disablesystemassertions
禁用系统断言
-agentlib:<libname>[=<选项>]
加载本机代理库 <libname>, 例如 -agentlib:hprof
另请参阅 -agentlib:jdwp=help 和 -agentlib:hprof=help
-agentpath:<pathname>[=<选项>]
按完整路径名加载本机代理库
-javaagent:<jarpath>[=<选项>]
加载 Java 编程语言代理, 请参阅 java.lang.instrument
-splash:<imagepath>
2.2.1 Combate real
1: Exibir versão jvm
[root@localhost ~]# java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) Server VM (build 25.201-b09, mixed mode)
[root@localhost ~]#
2: Defina os parâmetros de propriedade do sistema através de -D
/**
* @program: hgyq_app
* @ClassName TestJvm
* @description:
* @author: lyy
* @create: 2020-04-21 10:49
* @Version 1.0
**/
public class TestJvm {
public static void main(String[] args) {
String str = System.getProperty("str");
if(str == null){
System.out.println("muxiaonong");
}else{
System.out.println(str);
}
}
}
Compilar e testar:
# 编译
[root@localhost ~]# javac TestJvm.java
#测试
[root@localhost ~]# java TestJvm
muxiaonong
[root@localhost ~]# java -Dstr=520 TestJvm
520
2.2.2 - parâmetros do servidor e do cliente
Os parâmetros de execução da jvm podem ser configurados através de -server ou -client
- A diferença entre eles é que o espaço de heap inicial da VM do servidor será maior.Por padrão, o coletor de lixo paralelo é usado, que é iniciado lentamente e executado rapidamente.
- A VM do cliente será relativamente conservadora, o espaço de heap inicial será menor, usar um coletor de lixo serial, seu objetivo é acelerar o início da JVM, mas a velocidade de execução será mais lenta que o modo Serverm
- Quando a JVM é iniciada, ela escolhe automaticamente usar a JVM do Servidor ou Cliente de acordo com o hardware e o sistema operacional.
- Sistema operacional de 32 bits
1. Se for um sistema Windows, independentemente da configuração de hardware, a JVM do tipo cliente
é usada por padrão 2. Se for outro sistema operacional, a máquina está configurada com mais de 2 GB de memória e há mais de 2 CPUs, então o servidor é usado por padrão Modo, caso contrário, use o modo cliente - Sistema operacional de 64 bits
- Apenas tipo de servidor, tipo de cliente não é suportado
Teste ( esta máquina é um sistema operacional de 32 bits ):
# 参数操作系统位数
[root@localhost ~]# cat /proc/version
Linux version 2.6.32-358.el6.i686 (mockbuild@c6b8.bsys.dev.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) ) #1 SMP Thu Feb 21 21:50:49 UTC 2013
#设置Jvm的运行参数
[root@localhost ~]# java -client -showversion TestJvm
[root@localhost ~]# java -server -showversion TestJvm
2.3 -X parâmetros
parâmetros JVM -X de parâmetros não-padrão, diferentes versões de JVM, os argumentos podem não, você pode java -X
ver os parâmetros não-padrão
[root@localhost ~]# java -X
-Xmixed 混合模式执行 (默认)
-Xint 仅解释模式执行
-Xbootclasspath:<用 ; 分隔的目录和 zip/jar 文件>
设置搜索路径以引导类和资源
-Xbootclasspath/a:<用 ; 分隔的目录和 zip/jar 文件>
附加在引导类路径末尾
-Xbootclasspath/p:<用 ; 分隔的目录和 zip/jar 文件>
置于引导类路径之前
-Xdiag 显示附加诊断消息
-Xnoclassgc 禁用类垃圾收集
-Xincgc 启用增量垃圾收集
-Xloggc:<file> 将 GC 状态记录在文件中 (带时间戳)
-Xbatch 禁用后台编译
-Xms<size> 设置初始 Java 堆大小
-Xmx<size> 设置最大 Java 堆大小
-Xss<size> 设置 Java 线程堆栈大小
-Xprof 输出 cpu 配置文件数据
-Xfuture 启用最严格的检查, 预期将来的默认值
-Xrs 减少 Java/VM 对操作系统信号的使用 (请参阅文档)
-Xcheck:jni 对 JNI 函数执行其他检查
-Xshare:off 不尝试使用共享类数据
-Xshare:auto 在可能的情况下使用共享类数据 (默认)
-Xshare:on 要求使用共享类数据, 否则将失败。
-XshowSettings 显示所有设置并继续
-XshowSettings:all
显示所有设置并继续
-XshowSettings:vm 显示所有与 vm 相关的设置并继续
-XshowSettings:properties
显示所有属性设置并继续
-XshowSettings:locale
显示所有与区域设置相关的设置并继续
-X 选项是非标准选项, 如有更改, 恕不另行通知。
2.3.1 -Xint 、 -Xcomp 、 -Xmixed
-
No modo interpretado, o
-Xint
tag forçará a JVM a executar todo o bytecode, mas reduzirá a velocidade de execução, geralmente 10 vezes ou mais -
-Xcomp
O parâmetro-Xint
é exatamente o oposto dele ( ). Quando a JVM é usada pela primeira vez, ele compila todo o bytecode no código local, o que trará a otimização máxima- Muitos aplicativos em uso
-Xcomp
, haverá alguma perda de desempenho, mas que com-Xint
menos perda devido a-Xcomp
não deixar que a funcionalidade completa do JVM começar compilador JIT, compilador JIT pode precisar compilar fazer um julgamento se todo o código é compilado e, em seguida, Não faz sentido algum código que seja executado apenas uma vez
- Muitos aplicativos em uso
-
-Xmixed
É um modo misto.O modo de interpretação e o modo de compilação são misturados e usados, que é determinado pela jvm.Este é o modo padrão da jvm e o modo recomendado.
Exemplo: defina fortemente o modo de operação
# 强制设置为解释模式
[root@localhost ~]# java -showversion -Xint TestJvm
# 强制设置为编译模式
# 注意:在编译模式下,第一次执行会比
[root@localhost ~]# java -showversion -Xcomp TestJvm
# 默认的混合模式
[root@localhost ~]# java -showversion -Xmixed TestJvm
Parâmetros 2.4 -XX
O parâmetro -XX também é um parâmetro não padrão, usado principalmente para operações de ajuste e depuração da jvm. Os
parâmetros -XX são usados de duas maneiras: uma é do tipo booleano e a outra é do tipo não-booleano:
-
tipo booleano
- Formato:
-XX:[+-] <name>
marque ativar ou desativar o<name>
atributo, + significa aberto,-significa fechar - Como: -XX: + DisableExplicitGC significa desativar a chamada manual da operação gc, o que significa que a chamada System.gc () é inválida
- Formato:
-
Tipo não booleano
- Formato:
-XX:<name>=<value>
indica<name>
o valor do atributo<value>
- Por exemplo: -XX: NewRatio = 1 significa a proporção entre a nova geração e a geração antiga
- Formato:
-
Se deve imprimir detalhes da coleção do GC
- -XX: + PrintGCDetails
- -XX: -PrintGCDetails
-
Se um coletor de lixo serial deve ser usado
- -XX: + UseSerialGC
- -XX: -UserSerialGC
Depois de configurar o valor do atributo -XX: aqui,
inicie nosso método principal
Parâmetros de 2,5 -Xms e -Xmx
-Xms e -Xmx devem definir o tamanho inicial e o tamanho máximo da memória heap da jvm, respectivamente
-Xmx2048m: equivalente a -XX: MaxHeapSize, configure a memória heap máxima da JVM como 2048M
-Xms512m: equivalente a -XX: InitialHeapSize, configure a JVM inicial memória heap é 512M
tamanho de ajuste de memória JVM apropriado, pode tirar proveito de recursos do servidor, deixe o programa correr mais rápido
exemplo:
[root@localhost ~]# java -Xms512m -Xmx2048m TestJvm
muxiaonong
2.6 Ver parâmetros de execução do jvm
Às vezes, precisamos verificar os parâmetros de execução do jvm. Pode haver duas situações para esse requisito:
primeiro, imprima os parâmetros de execução ao executar o comando java;
segundo, visualize os parâmetros do processo em execução do java;
2.6.1 Parâmetros de impressão ao executar o comando java
java -XX:+PrintFlagsFinal -version
Como pode ser visto na informação acima mencionada, um booleano parâmetros e tipo numérico, o operador é o valor =
ou :=
os valores que representam o valor padrão e o modificado
Três, modelo de memória JVM
O modelo de memória da jvm tem uma grande diferença entre 1.7 e 1.8.Embora 1.8 seja usado como exemplo neste artigo, também entenderemos o modelo de memória do 1.7. Então, primeiro vamos entender o modelo de memória do 1.7 learning 1.8
3.1, modelo de memória heap jdk1.7
-
Área Young (geração) A
área Young é dividida em três partes: a área Eden e as duas áreas Survivor exatamente do mesmo tamanho: entre as áreas Survivor, apenas uma é usada por vez e a outra é reservada para coleta de lixo. Para copiar objetos, quando o intervalo Eden ficar cheio, o GC moverá os objetos sobreviventes para o intervalo Survivor livre.De acordo com a estratégia da JVM, após várias coletas de lixo, os objetos que ainda sobrevivem no Survivor são movidos para Intervalo de posse. -
Tenured A
área Tenured salva principalmente objetos com um longo ciclo de vida, geralmente alguns antigos. Quando alguns objetos são copiados e transferidos por Young por um certo número de vezes, os objetos serão transferidos para a área Tenured. Geralmente, se o nível do aplicativo Cache, os objetos no cache são frequentemente transferidos para esse intervalo -
região de Perm Permanente
Perm página salvarclass、method、filed对象
, este espaço não é geralmente parte do estouro, a menos que uma carga descartável muita classe, mas em design para a implementação ativa de servidores de aplicação, quando, por vezes, encontrarjava.lang.OutOfMempryError:PermGen Space
um bug que causou este erro Um grande motivo é que ela pode ser reimplantada toda vez, mas após a reimplementação, a classe de classe não é desinstalada, o que faz com que um grande número de objetos de classe seja salvo no permanente. Resolver o problema -
Área virtual
A diferença entre a memória máxima e a memória inicial é a área virtual
3.2, modelo de memória heap jdk1.8
Pode ser visto pela figura acima que o modelo de memória do jdk1.8 é composto por 2 partes, geração jovem + geração antiga
: Eden + 2 *
geração antiga de sobrevivente : OldGen
na área de Perm com a maior alteração no jdk1.8, use A substituição do Metaspace (espaço de metadados)
precisa de uma explicação especial: o espaço de memória ocupado pelo Metaspace não está dentro da máquina virtual, mas no espaço de memória local, que é a maior diferença da geração permanente de 1,7
3.3 Por que a área permanente em 1.7 deve ser abandonada?
Sobre o motivo pelo qual a área permanente em 1.7 foi abandonada, podemos ver a descrição no site oficial, o endereço do site oficial: http://openjdk.java.net/jeps/122
Isso faz parte do esforço de convergência JRockit e Hotspot. Os clientes JRockit não precisam configurar a geração permanente (já que o JRockit não possui uma geração permanente) e estão acostumados a não configurar a geração permanente.
#Remover a geração permanente é um esforço para integrar a Hot Spot JVm e a JRockit VM, porque o Jrockit não possui uma geração permanente e não há necessidade de configurar uma geração permanente
Em nosso uso real, porque a geração permanente de memória geralmente não é suficiente ou ocorre um vazamento de memória e uma exceção é relatada java.lang.OutOfMempryError:PermGen
, a área permanente é abandonada e o meta espaço é usado em vez de usar o espaço de memória local
3.4 Exibir o uso de memória heap através do comando jstat
O comando jstat pode exibir o uso de várias partes da memória heap e o número de classes carregadas.O formato do comando é o seguinte:
jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]
3.4.1 Exibir estatísticas de carregamento de classe
[root@localhost ~]# jstat -class 20736
Explicação:
Método | Descrição do produto |
---|---|
Carregado | Número de classes carregadas |
Bytes | Espaço ocupado |
Descarregado | Quantidade descarregada |
Bytes | Espaço não carregado |
Tempo | Tempo |
3.4.2 Ver estatísticas de compilação
[root@localhost ~]# jstat -compiler 20736
Método | Descrição do produto |
---|---|
Compilado | Número de compilações |
Falhou | Número de falhas |
Inválido | Quantidade indisponível |
Tempo | Tempo |
FailedType | Tipo de falha |
FailedMethod | Método com falha |
3.4.3 Estatísticas de coleta de lixo
[root@localhost ~]# jstat -gc 20736
S0C: O tamanho da primeira área de Survivor (KB)
S1C: O tamanho da segunda área de Survivor (KB)
S0U: O tamanho da primeira área de Survivor (KB) S1U: O tamanho da
segunda área de Survivor (KB)
CE: tamanho da área Eden (KB)
UE: tamanho da área Eden (KB)
OC: tamanho da área antiga (KB)
OU: tamanho da área antiga (KB)
MC: tamanho da área do método (KB)
MU: tamanho da área do método (KB)
CCSC: tamanho do espaço de classe compactado (KB)
CCSU: tamanho do uso de espaço de classe compactado (KB)
YGC: tempos de coleta de lixo de gerações jovens
YGCT: tempo de coleta de lixo de gerações jovens
FGC: tempos de coleta de lixo de gerações anteriores
FGCT: tempos de coleta de lixo de gerações antigas FGCT: tempos de coleta de lixo de gerações antigas Tempo decorrido no
TCG: tempo total consumido pela coleta de lixo
4. Resumo
O artigo está finalizado aqui.Os irmãos em dúvida podem discutir ou deixar uma mensagem abaixo.Eu também desejo a todos um feliz ano, saudável e saudável, e um bom trabalho.Vamos, eu sou um pequeno agricultor!