Montón de JVM y ajuste del montón y cómo solucionar problemas de OOM

Tuning ubicación - montón

Montón, una JVM tiene solo una memoria de montón, y el tamaño de la memoria de montón se puede ajustar.
Después de que el cargador de clases lea el archivo de clase, ¿qué colocará normalmente en el montón? Clases, métodos, constantes, variables ~, guarde los objetos reales de todos nuestros tipos de referencia; la memoria del montón también se subdivide en tres áreas: 1.
Recién
nacido Zona (Zona 0/Zona 1): El lugar donde nacen, crecen e incluso mueren las clases. Entre ellos, el área de Eden es donde ocurren todos los objetos nuevos.
2. Área de retiro: Los objetos que sobrevivieron al GC del área nueva ingresan al área de retiro
3. Área permanente: Esta área reside en la memoria. Se utiliza para almacenar el objeto Class que lleva el propio DK. Los metadatos de la interfaz almacenan información sobre el entorno o la clase cuando se ejecuta Java. ¡No hay recolección de basura en esta área! Al desactivar la virtualización de la VM, se liberará la memoria en esta área

. , campo, etc.
inserte la descripción de la imagen aquí
Las áreas sobrevivientes 0 y 1 son un cambio dinámico en la memoria del montón. Es una transición entre el área Eden y el área de retiro. Como su nombre lo indica, los objetos que no puedan sobrevivir serán "matados". Basura GC la recogida se realiza principalmente en la nueva zona Se llevan a cabo The Eden Park y Elderly Care Area en China . Los métodos de reciclaje se dividen en GC ligero y GC pesado. El GC ligero existe principalmente en el área nueva. Solo cuando los objetos de basura que ingresan al área antigua superan el límite, se activará el GC pesado (GC completo). Esta operación existe principalmente en la zona antigua.
inserte la descripción de la imagen aquí
Es posible que encuentre problemas de OOM durante el desarrollo, lo que indica que no hay suficiente memoria. Esta memoria también es la memoria del montón de la JVM, como el siguiente ejemplo:
Excepción en el hilo "principal" java.lang.OutOfMemoryError:
inserte la descripción de la imagen aquí
99% de los objetos en el espacio de almacenamiento dinámico de Java son objetos temporales, por lo que después de GC, rara vez ingresa al área anterior, por lo que rara vez ocurre OOM

Evolución de la zona permanente

Esta área es residente en la memoria. Se utiliza para almacenar el objeto Class que lleva el propio IDK. Metadatos de la interfaz, que almacenan información sobre el entorno o la clase del tiempo de ejecución de Java.

Antes de jdk1.6: generación permanente, el grupo constante está en el área de métodos;
jdk1.7: generación permanente, pero degenera lentamente, vaya a la generación permanente, el grupo constante está en el montón
Después de jdk1.8: sin generación permanente, el grupo constante está en Metaspace

inserte la descripción de la imagen aquí

El surgimiento de OOM

El caso de corrupción de memoria en el área permanente: una clase de inicio carga una gran cantidad de paquetes jar de terceros. Tomcat implementa demasiadas aplicaciones y una gran cantidad de clases de reflexión generadas dinámicamente. Estar constantemente cargado. OOM aparecerá hasta que la memoria esté llena;
inserte la descripción de la imagen aquí
de forma predeterminada: la memoria total asignada es un cuarto de la memoria de la computadora y la memoria inicializada es una sesenta y cuatro parte de la memoria de la computadora,
pero estos parámetros de memoria se pueden ajustar manualmente para
inserte la descripción de la imagen aquí
ejecutar el programa Después de eso, se encuentra que los parámetros de JVM han cambiado
inserte la descripción de la imagen aquí

Se puede ver que el metaespacio existe lógicamente pero no físicamente.

Cómo solucionar problemas de OOM

Puede usar herramientas de instantáneas de memoria para analizar objetos, principalmente: MAT (Eclipse), Jprofile (IDEA) dos herramientas.
Simplemente pase los siguientes parámetros a la máquina virtual.
inserte la descripción de la imagen aquí
Cuando el programa se ejecute y ocurra OOM, vaya al directorio de archivos donde se encuentra la clase para encontrar el archivo hprof generado por Jprofile.
inserte la descripción de la imagen aquí

Haga doble clic para abrirlo y encontrar inicialmente objetos que ocupan una gran cantidad de memoria, comúnmente conocidos como "objetos grandes".
inserte la descripción de la imagen aquí

Vea el hilo (Thread Dump) para encontrar la línea donde ocurre el problema en el programa.
inserte la descripción de la imagen aquí
De acuerdo con la situación específica, puede ajustar los parámetros de ajuste relacionados con JVM:
inserte la descripción de la imagen aquí
Comparta algunos otros parámetros de JVM:
-Xmx4g: la memoria de almacenamiento dinámico máxima es de 4 GB.
-Xms4g: inicializa el tamaño de la memoria del montón a 4 GB.
-Xmn1200m: establezca el tamaño de la generación joven en 1200 MB . Después de aumentar la generación joven, se reducirá el tamaño de la generación anterior. Este valor tiene un gran impacto en el rendimiento del sistema y Sun recomienda oficialmente configurarlo como 3/8 del montón completo.
-Xss512k: establece el tamaño de la pila por subproceso . Después de JDK5.0, el tamaño de la pila de cada subproceso es de 1 MB, y antes el tamaño de la pila de cada subproceso era de 256 K. Debe ajustarse de acuerdo con el tamaño de memoria requerido por el subproceso de la aplicación. Bajo la misma memoria física, reducir este valor puede generar más hilos. Sin embargo, el sistema operativo todavía tiene un límite en la cantidad de subprocesos en un proceso y no se puede generar infinitamente. El valor de la experiencia es de alrededor de 3000~5000.
-XX:NewRatio=4: Establece la proporción de la generación joven (incluyendo Eden y dos áreas de Supervivientes) a la generación anterior (excluyendo la generación permanente) . Si se establece en 4, la proporción de la generación joven a la generación anterior es 1: 4, y la generación joven ocupa 1/5 de toda la pila.
-XX: SurvivorRatio = 8: establezca la proporción de tamaño del área de Eden al área Survivor en la generación joven . Si se establece en 8, la proporción de dos áreas de Supervivientes por un área de Eden es de 2:8, y un área de Supervivientes representa 1/10 de toda la generación joven. -XX:PermSize=100m: inicializa
el tamaño de generación permanente para 100MB _
-XX:TamañoMáximoPerm=256m:Establezca el tamaño de generación persistente en 256 MB .
-XX:MaxTenuringThreshold=15: establecer la edad máxima de basura . Si se establece en 0, el objeto de generación joven no pasará por
los parámetros ajustables:
-Xms: inicializa el tamaño de la memoria del montón, el valor predeterminado es 1/64 de la memoria física (menos de 1 GB) .
-Xmx: **El valor máximo de la memoria del montón. **De forma predeterminada (el parámetro MaxHeapFreeRatio se puede ajustar) cuando la memoria de montón libre es superior al 70 %, la JVM reducirá el montón hasta el límite mínimo de -Xms.
-Xmn: El tamaño de la nueva generación, incluyendo el área Eden y 2 áreas Survivor .
-XX:SurvivorRatio=1: La relación entre el área de Eden y el área de Survivor es 1:1 .
-XX:MaxDirectMemorySize=1G: ** memoria directa. **Informe java.lang.OutOfMemoryError: la excepción de memoria de búfer directa puede aumentar este valor.
-XX:+DisableExplicitGC: Prohibir que el tiempo de ejecución llame explícitamente a System.gc() para activar el GC completo .
Nota: El mecanismo de activación de GC de sincronización de Java RMI se puede configurar para controlar el tiempo de activación configurando -Dsun.rmi.dgc.server.gcInterval=86400.
-XX:CMSInitiatingOccupancyFraction=60: Umbral de recuperación de memoria antigua, el valor predeterminado es 68 .
-XX:ConcGCThreads=4: subprocesos paralelos del recolector de elementos no utilizados de CMS, el valor recomendado es el número de núcleos de CPU .
-XX:ParallelGCThreads=8: el número de subprocesos para el recopilador paralelo de nueva generación .
-XX:MaxTenuringThreshold=10: establece la edad máxima de basura . Si se establece en 0, los objetos de la generación joven ingresarán directamente a la generación anterior sin pasar por el área Superviviente. Para aplicaciones con generaciones más antiguas, se puede mejorar la eficiencia. Si este valor se establece en un valor mayor, el objeto de la generación joven se copiará varias veces en el área Superviviente, lo que puede aumentar el tiempo de supervivencia del objeto en la generación joven y aumentar la probabilidad de que se recicle en la generación joven.
-XX:CMSFullGCsBeforeCompaction=4: después de especificar cuántas veces se realiza fullGC, se comprime el espacio de memoria en el área de tenencia .

-XX:CMSMaxAbortablePrecleanTime=500: Cuando la ejecución de la fase de prelimpieza abortable-preclean llegue a este tiempo, finalizará .

Supongo que te gusta

Origin blog.csdn.net/weixin_57535055/article/details/129232440
Recomendado
Clasificación