Capítulo 25 Parámetros de tiempo de ejecución de JVM
JVM explicado por Song Hongkang de Shang Silicon Valley: enlace bilibili
1 tipo de opción de parámetro JVM
1.1 Tipo 1: Opciones de parámetros estándar
-
Características: relativamente estable, básicamente sin cambios en versiones posteriores, comenzando con-
-
Varias opciones: ejecute java o java -help para ver todas las opciones estándar
-
Carga interna complementaria: -servidor y -cliente
Hotspot JVM tiene dos modos, servidor y cliente, respectivamente, establecidos por los modos -server y -client
- En los sistemas Windows de 32 bits, el tipo de cliente JVM se utiliza de forma predeterminada. Para utilizar el modo de servidor, la máquina debe tener al menos 2 CPU y 2G o más de memoria física. El modo cliente es adecuado para aplicaciones de escritorio con poca memoria, y el recolector de basura serial se usa por defecto.
- En máquinas de 64 bits, solo se admite JVM en modo servidor. Se usa para aplicaciones que requieren gran memoria. El recolector de basura paralelo se usa de manera predeterminada.
-
Acerca del sitio web oficial del servidor y el cliente: URL
1.2 Tipo dos: parámetro -X
-
Características: Parámetros no estandarizados, la función es relativamente estable. Pero el funcionario dijo que las versiones posteriores pueden cambiarse, comenzando con -X
-
Varias opciones: ejecute el comando java -X para ver todas las opciones de X
-
Opciones relacionadas con el modo de compilación JIT de JVM
-Xint deshabilita JIT, todos los códigos de bytes se interpretan y ejecutan, este modo es el más lento
-Xcomp Todos los códigos de bytes se compilan en códigos locales la primera vez que se utilizan y luego se ejecutan
-Modo mixto Xmixed, el modo predeterminado, permite a JIT compilar selectivamente algún código en código local de acuerdo con la situación de ejecución del programa
-
especial
-Xms -Xmx -Xss pertenece al parámetro XX
- -Xms <tamaño> establece el tamaño del montón de Java inicial, que es equivalente a -XX: InitialHeapSize
- -Xmx <tamaño> establece el tamaño máximo de almacenamiento dinámico de Java, que es equivalente a -XX: MaxHeapSize
- -Xss <tamaño> establece el tamaño de la pila de subprocesos de Java, que es equivalente a -XX: ThreadStackSize
1.3 Tipo tres: parámetro -XX
-
Características: Parámetros no estandarizados, las opciones de parámetros más utilizadas , tales opciones son experimentales e inestables. Empiece con -XX
-
Rol: utilizado para desarrollar y depurar JVM
-
Categoría :
ejemplo:
# Boolean类型格式 -XX:+UseParallelGC # 选择垃圾收集器为并行收集器 -XX:+UseG1GC # 表示启用G1收集器 -XX:+UseAdaptiveSizePolicy # 自动选择年轻代区大小和响相应的Survivor区比例 # 非Boolean类型格式(key-value类型) # 子类型1:数值型格式 -XX:<option>=<number> # number表示数值,可带上单位:(兆:'m','M'),(KB:'k', 'K'), (GB:'g','G') -XX:NewSize=1024m # 表示设置新生代初始大小为1024兆 -XX:MaxGCPauseMills=500 # 表示设置GC停顿时间:500毫秒 -XX:GCTimeRatio=19 # 表示设置吞吐量 -XX:NewRatio=2 # 表示老年代和新生代的比例为2 # 子类型1:非数值型格式 -XX:<option>=<string> -XX:HeapDumpPath=/usr/local/heapdump.hprof # 用于指定heap转存文件的存储路径
-
En particular:
-XX:+PrintFlagsFinal
- Salida de los nombres y valores predeterminados de todos los parámetros
- Los parámetros de Diagnosticc y Experiment no se incluyen por defecto
- Puede cooperar
-XX:+UnlockDiagnosticVMOptions
y-XX:UnlockExperimentVMOptions
usar
2 Agregar opciones de parámetros de JVM
eclipse
...
IDEA
Ejecuta el paquete jar
java -Xms50m -Xmx50m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar demo.jar
Ejecute el paquete de guerra a través de Tomcat
- En el sistema Linux, puede agregar la siguiente configuración en tomcat / bin / catalina.sh:
JAVA_OPTS="-Xms512M -Xmx1024M"
- Agregue una configuración similar a la siguiente en catalina.bat en el sistema Windows:
set "JAVA_OPTS=-Xms512M -Xmx1024M"
Mientras el programa se está ejecutando
- Úselo para
jinfo -flag <name>=<value> <pid>
establecer parámetros de tipo no booleano - Úselo para
jinfo -flag [+|-]<name> <pid>
establecer parámetros de tipo booleano
3 Opciones de parámetros de JVM más utilizadas
3.1 XX opciones y valores de la configuración de impresión
3.2 Configuraciones de tamaño de memoria como montón, pila, área de método, etc.
- Nota: Aunque los parámetros predeterminados
-XX:SurvivorRatio=8
no se configuran explícitamente, de hecho Eden: S0: S1 = 6: 1: 1 (por defecto,-XX:+UseAdaptivePolicy
está encendido, incluso si la opción está desactivada, pero la configuración explícita no está configurada-XX:SurvivorRatio=8
, el La proporción real sigue siendo 6: 1: 1). Siempre que se establezca explícitamente-XX:SurvivorRatio=8
, Eden: S0: S1 = 8: 1: 1.
3.3 Opciones relacionadas con OutofMemory
-
Operación y mantenimiento de OnOutOfMemoryError
Tome el Server.jar implementado en el directorio / opt / Server del sistema Linux como ejemplo
(1) Agregue parámetros jvm en el script de inicio run.sh
-XX:OnOutOfMemoryError=/opt/Server/restart.sh
(2) script de reinicio.sh
entorno linux
#!/bin/bash pid=$(pf -ef | grep Server.jar | awk '{ if($8=="java"){ print $2}}') kill -9 $pid cd /opt/Server/;sh run.sh
entorno de windows
echo off wmic process where Name='java.exe' delete cd D:\Server start run.bat
3.4 Opciones relacionadas con el recolector de basura
-
La relación entre los 7 recolectores de basura clásicos y la generación de basura
-
Combinación de recolector de basura
-
La figura se ha actualizado a JKD14.
- Si las líneas punteadas en la figura se consideran líneas continuas, esta es la combinación de recolectores de basura antes de JDK8 (sin incluir JDK8)
- La línea entre CMS y MSC significa que si CMS falla, inicie MSC (MSC es equivalente a una solución de respaldo)
- La combinación de las dos líneas discontinuas rojas se abandonó en JDK8 (JEP 173) y las dos líneas discontinuas rojas se eliminaron en JDK9 (JEP 214).
- En JDK14, la combinación de la línea discontinua verde (JEP 366) está obsoleta .
- En JDK14, se elimina el recolector de basura CMS (JEP 363) en el cuadro de puntos cian .
-
El recolector de basura predeterminado en JDK8 es: Parallel Scavenge GC + Parallel Old GC
-
¿Por qué no se puede utilizar Parallel Scanvenge GC con CMS?
- El marco utilizado en la parte inferior de Parallel Scanvenge GC es diferente e incompatible con otros.
-
-
mapas mentales
Ver el recolector de basura predeterminado
-XX:+PrintCommandLineFlags # 查看命令行相关参数(包含使用的垃圾收集器)
Utilice las instrucciones de la línea de comandos:
jinfo -flag 相关垃圾收集器参数 进程ID
Colector en serie
El recolector serial sirve como recolector de basura de nueva generación predeterminado en el modo Cliente de HotSpot. Serial Old es el recolector de basura predeterminado de la generación anterior que se ejecuta en modo Cliente.
-XX:+UseSerialGC
Especifique que tanto la generación joven como la generación anterior utilizan colectores en serie. Es equivalente a usar Serial GC en la nueva generación y Serial Old GC en la generación anterior. Se puede obtener la mayor eficiencia de recolección de un solo hilo.
ParNew coleccionista
-XX:UseParNewGC
Especifique manualmente utilizar el recopilador ParNew para realizar tareas de recuperación de memoria. Significa que la generación joven usa el colector paralelo y no afecta a la generación anterior.
-XX:ParallelGCThreads=N
Limite el número de subprocesos. De forma predeterminada, el número de subprocesos con los mismos datos de CPU está habilitado.
Colector paralelo (prioridad de rendimiento)
- Configuración de parámetros
- -XX: + UseParallelGC especifica manualmente la nueva generación para usar el recopilador paralelo paralelo para realizar tareas de recuperación de memoria.
- -XX: UseParallelOldGC especifique manualmente la generación anterior para usar el recopilador de recopilación paralelo.
- Es aplicable a la nueva generación y la vieja generación respectivamente, y jdk8 está habilitado de forma predeterminada.
- De los dos parámetros anteriores, uno está habilitado de forma predeterminada y el otro también estará habilitado. (Activación mutua)
- -XX: ParallelGCThreads establece el número de subprocesos del recolector paralelo de nueva generación. Generalmente, es mejor ser igual al número de CPU para evitar que el exceso de subprocesos afecte el rendimiento de la recolección de basura.
- De forma predeterminada, cuando el número de CPU es menor o igual a 8, el valor de ParallelGCThreads es igual al número de CPU.
- Cuando el número de CPU es mayor que 8, el valor de ParallelGCThreads es igual a 3+ [5 * CPU_count / 8].
- -XX: MaxGCPauseMillis diseña el tiempo máximo de pausa del recolector de basura (es decir, el tiempo de STW). La unidad es milisegundos.
- Para mantener el tiempo de pausa dentro de MaxGCPauseMillis tanto como sea posible, el recolector ajustará el tamaño del montón de Java o algunos otros parámetros cuando esté trabajando.
- Para los usuarios, cuanto más corto sea el tiempo de pausa, mejor será la experiencia, pero en el lado del servidor, nos enfocamos en una alta concurrencia y rendimiento general. Entonces, el lado del servidor es adecuado para Parallel para el control.
- Utilice este parámetro con precaución.
- -XX: GCTimeRatio La relación entre el tiempo de recolección de basura y el tiempo total (= 1 / (N + 1)). Se utiliza para medir el tamaño del rendimiento.
- Rango de valores (0, 100). El valor predeterminado es 99, lo que significa que el tiempo de recolección de basura no supera el 1%.
- Existe una cierta contradicción con el parámetro -XX: MaxGCPauseMillis anterior. Cuanto menor sea el tiempo de pausa, más fácil será que el parámetro Ratio exceda el ratio establecido.
- -XX: + UseAdaptiveSizePolicy configura el recopilador Parallel Scavenge para que tenga una estrategia de ajuste adaptable .
- En este modo, el tamaño de la generación joven, la proporción de Eden y Survivor y la edad de los objetos promovidos a la generación anterior se ajustan automáticamente para lograr un equilibrio entre el tamaño del montón, el rendimiento y el tiempo de pausa.
- En situaciones en las que el ajuste manual es difícil, puede usar directamente este método adaptativo para especificar solo el montón máximo, el rendimiento objetivo (GCTimeRatio) y el tiempo de pausa (MaxGCPauseMillis) de la máquina virtual, y dejar que la máquina virtual complete el trabajo de ajuste por sí misma.
Recopilador de CMS (baja latencia)
-
Configuración de parámetros
- -XX: UseConcMarkSweepGC especifica manualmente el uso del recopilador CMS para realizar tareas de recuperación de memoria.
- Después de activar este parámetro, -XX: + UseParNewGC se activará automáticamente. Es decir, la combinación de ParNew (para el área Young) + CMS (para el área Old) + Serial Old.
- -XX: CMSInitiatingOccupanyFraction establece el umbral de uso de la memoria del montón, una vez que alcanza el umbral, comienza a reciclarse.
- El valor predeterminado de JDK5 y versiones anteriores es 68, es decir, cuando la tasa de utilización de la generación anterior alcanza el 68%, se realizará una recuperación de CMS. El valor predeterminado de JDK6 y superior es 92% .
- Si la memoria crece lentamente, esto se puede establecer en un valor mayor. Un umbral mayor puede reducir efectivamente la frecuencia de inicio del CMS, y la reducción del número de reciclaje en la generación anterior puede mejorar significativamente el rendimiento de la aplicación. Por el contrario, si el uso de la memoria aumenta rápidamente, este umbral debe reducirse para evitar la activación frecuente del antiguo colector en serie. Por lo tanto, esta opción puede reducir efectivamente el número de ejecuciones de Full GC .
- -XX: UseCMSCompactAtFullCollection se utiliza para especificar la compresión y clasificación de la memoria después de que se ejecuta el GC completo, para evitar la generación de fragmentación de la memoria. Sin embargo, debido a que el proceso de clasificación y compresión de la memoria no se puede ejecutar al mismo tiempo, el problema es que el tiempo de pausa se alarga.
- -XX: CMSFullGCsBeforeCompaction establece cuántas veces se ejecuta Full GC para comprimir y organizar el espacio de memoria.
- -XX: ParallelCMSThreads establece el número de subprocesos CMS.
- El número de subprocesos habilitados por CMS de forma predeterminada es (ParallelGCThreads + 3) / 4. ParallelGCThreads es el número de subprocesos del recopilador paralelo de nueva generación. Cuando los recursos de la CPU son limitados, el recopilador CMS se ve afectado. El rendimiento de la aplicación puede Estar en la fase de recolección de basura será muy malo.
- -XX: UseConcMarkSweepGC especifica manualmente el uso del recopilador CMS para realizar tareas de recuperación de memoria.
-
Parámetros suplementarios
-
instrucciones especiales
Colector G1
-
configuración de parámetros
- -XX: UseG1GC especifica manualmente el uso del recolector G1 para realizar tareas de recuperación de memoria.
- -XX: G1HeapRegionSize establece el tamaño de cada región. El valor es una potencia de 2 y el rango está entre 1 MB y 32 MB. El objetivo es dividir 2048 regiones en función del tamaño de almacenamiento dinámico de Java más pequeño. La región es 1/2000 de memoria dinámica de forma predeterminada.
- -XX: MaxGCPauseMillis establece el índice de tiempo de pausa de GC máximo esperado (JVM hará todo lo posible para lograrlo, pero no se garantiza que se alcance). El valor predeterminado es 200 ms.
- -XX: ParallelGCThread establece el valor del número de subprocesos GC en STW. Fije a 8 como máximo.
- -XX: ConcGCThreads establece el número de subprocesos marcados simultáneamente. Se recomienda establecer este parámetro en aproximadamente 1/4 de los subprocesos de recolección de basura paralelos (ParallelGCThreads).
- -XX: InitiatingHeapOccupancyPercent establece el umbral de ocupación del montón de Java que activa los ciclos de GC concurrentes. Si se excede este valor, se activa GC. El valor predeterminado es 45.
- -XX: G1NewSizePercent, -XX: G1MaxNewSizePercent el porcentaje mínimo (predeterminado 5%) y el porcentaje máximo (predeterminado 60%) de la nueva generación de toda la memoria del montón
- -XX: G1ReservePercent reserva el área de memoria para evitar que el espacio (al área en Survivor) se desborde
-
Parámetros de ajuste de GC mixtos
Cómo elegir un recolector de basura
La configuración del recolector de basura de Java es una opción importante para la optimización de la JVM. La elección de un recolector de basura adecuado puede mejorar en gran medida el rendimiento de la JVM.
- Priorice el ajuste del tamaño del montón para permitir que la JVM se complete de forma adaptativa
- Si la memoria es inferior a 100 MB, utilice el colector en serie
- Si es un programa de un solo núcleo, independiente y no hay requisitos de tiempo de pausa, el colector en serie
- Si es multi-CPU, requiere un alto rendimiento y permite un tiempo de pausa de más de 1 segundo, elija paralelo o JVM para elegirlo usted mismo.
- Si se trata de una CPU múltiple, la búsqueda del tiempo de pausa, la respuesta rápida (por ejemplo, el retraso no puede ser ultra alto de 1 segundo, como las aplicaciones de Internet), utilice un colector concurrente; la recomendación oficial G1, alto rendimiento. Ahora los proyectos de Internet utilizan básicamente G1 .
- Finalmente, un punto claro
- No existe el mejor coleccionista, y no hay un colector universal; el ajuste siempre está dirigido a escenarios específicos y necesidades específicas, y no hay un colector de una vez por todas.
3.5 Opciones relacionadas con el registro de GC
3.6 Otros parámetros
4 Obtenga parámetros de JVM a través del código Java
- Java proporciona el paquete java.lang.management para monitorear y administrar la máquina virtual Java y otros componentes en el tiempo de ejecución de Java. Permite el monitoreo y administración local y remota de la máquina virtual Java en ejecución. Entre ellos, la clase ManagementFactory se usa con bastante frecuencia. Además, hay una clase en tiempo de ejecución que también puede obtener algo de memoria, número de núcleo de CPU y otros datos relacionados.
- A través de estas API, podemos monitorear el uso de la memoria del montón del servidor de aplicaciones y establecer algunos umbrales para el procesamiento de alarmas.
/**
* 监控我们的应用服务器的堆内存使用情况,设置一些阈值进行报警等处理
*/
public class MemoryMonitor {
public static void main(String[] args) {
MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean();
MemoryUsage usage = memorymbean.getHeapMemoryUsage();
System.out.println("INIT HEAP: " + usage.getInit() / 1024 / 1024 + "m");
System.out.println("MAX HEAP: " + usage.getMax() / 1024 / 1024 + "m");
System.out.println("USE HEAP: " + usage.getUsed() / 1024 / 1024 + "m");
System.out.println("\nFull Information:");
System.out.println("Heap Memory Usage: " + memorymbean.getHeapMemoryUsage());
System.out.println("Non-Heap Memory Usage: " + memorymbean.getNonHeapMemoryUsage());
System.out.println("=======================通过java来获取相关系统状态============================ ");
System.out.println("当前堆内存大小totalMemory " + (int) Runtime.getRuntime().totalMemory() / 1024 / 1024 + "m");// 当前堆内存大小
System.out.println("空闲堆内存大小freeMemory " + (int) Runtime.getRuntime().freeMemory() / 1024 / 1024 + "m");// 空闲堆内存大小
System.out.println("最大可用总堆内存maxMemory " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "m");// 最大可用总堆内存大小
}
}
/*
INIT HEAP: 256m
MAX HEAP: 3614m
USE HEAP: 5m
Full Information:
Heap Memory Usage: init = 268435456(262144K) used = 5383480(5257K) committed = 257425408(251392K) max = 3790077952(3701248K)
Non-Heap Memory Usage: init = 2555904(2496K) used = 4789360(4677K) committed = 8060928(7872K) max = -1(-1K)
=======================通过java来获取相关系统状态============================
当前堆内存大小totalMemory 245m
空闲堆内存大小freeMemory 240m
最大可用总堆内存maxMemory 3614m
*/