JVM gestiona dos tipos de memoria, dinámica y no dinámica. El montón es para que lo utilicen los desarrolladores, como se mencionó anteriormente, se crea cuando se inicia la JVM; el no montón está reservado para que la propia JVM almacene información de clase. A diferencia del montón, GC no liberará espacio durante el tiempo de ejecución.
1. Tipo de desbordamiento de memoria
1. java.lang.OutOfMemoryError: espacio PermGen
JVM gestiona dos tipos de memoria, dinámica y no dinámica. El montón es para que lo utilicen los desarrolladores, como se mencionó anteriormente, se crea cuando se inicia la JVM; el no montón está reservado para que la propia JVM almacene información de clase. A diferencia del montón, GC no liberará espacio durante el tiempo de ejecución. Si la aplicación web utiliza una gran cantidad de archivos jar de terceros o la aplicación tiene demasiados archivos de clase y la configuración de MaxPermSize resulta ser pequeña, exceder el límite también hará que la memoria ocupe demasiada y provocará un desbordamiento, o el Tomcat No limpie el frente durante la implementación en caliente. El entorno cargado solo cambiará el contexto al recién implementado y habrá cada vez más contenido no acumulable.
El nombre completo del espacio PermGen es Espacio de generación permanente, que se refiere al área de almacenamiento permanente de la memoria. Esta memoria es utilizada principalmente por la JVM para almacenar la información de clase y meta que se colocará en el espacio PermGen. Lo carga Loader y almacena instancias de clase (Instancia). El área del montón es diferente, GC (recolección de basura) no limpiará el espacio PermGen durante la ejecución del programa principal, por lo que si su aplicación tiene mucha CLASE, una. Es probable que se produzca un error de espacio PermGen. Este error es común cuando el servidor web precompila JSP. Si su APLICACIÓN WEB utiliza una gran cantidad de archivos jar de terceros y su tamaño excede el tamaño predeterminado de jvm (4M), se generará este mensaje de error.
Un mejor ejemplo de configuración: (Después de verificarlo yo mismo, desde que usé esta configuración, Tomcat nunca ha vuelto a morir)
establecer JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m
En Linux, agregue una línea de código como se muestra en rojo en tomcathome/conf/catalina.sh: puede aumentar la memoria de tomcat jvm, para que sea menos probable que se produzca un desbordamiento de memoria.
# ----- Ejecutar el comando solicitado ---------------------------------------- -
JAVA_OPTS="-servidor -Xms512m -Xmx2048m -XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=256m"
# Bugzilla 37848: solo genera esto si tenemos un TTY
2. java.lang.OutOfMemoryError: espacio del montón de Java
La primera situación es un complemento y el principal problema se produce en esta situación. Su espacio predeterminado (es decir, -Xms) es 1/64 de la memoria física y el espacio máximo (-Xmx) es 1/4 de la memoria física. Si queda menos del 40% de la memoria, la JVM aumentará el montón al valor establecido por Xmx. Si la memoria restante excede el 70%, la JVM disminuirá el montón al valor establecido por Xms. Por lo tanto, las configuraciones Xmx y Xms del servidor generalmente deben configurarse de la misma manera para evitar ajustar el tamaño del montón de la máquina virtual después de cada GC. Suponiendo que la memoria física es infinita, la memoria JVM máxima depende del sistema operativo. Generalmente, la máquina de 32 bits está entre 1,5 gy 3 g, mientras que la máquina de 64 bits no tiene límite.
Nota: Si Xms excede el valor Xmx, o la suma del valor máximo del montón y el valor máximo no montón excede el límite máximo de memoria física o del sistema operativo, el servidor no se iniciará.
El papel de la recolección de basura GC
La frecuencia con la que JVM llama a GC sigue siendo muy alta y la recolección de basura se realiza en dos situaciones principales:
Cuando el subproceso de la aplicación está inactivo; el otro es cuando el montón de memoria de Java es insuficiente, se llamará continuamente al GC. Si el reciclaje continuo no puede resolver el problema del montón de memoria insuficiente, se informará un error de falta de memoria. Debido a que esta excepción depende del entorno operativo del sistema, es imposible predecir cuándo ocurrirá.
Según el mecanismo de GC, la ejecución del programa provocará cambios en el entorno operativo del sistema, lo que aumentará las posibilidades de que se active GC.
Para evitar estos problemas, el diseño y la escritura de programas deben evitar la ocupación de memoria de los objetos basura y la sobrecarga de GC. Llamar explícitamente a System.GC() solo puede sugerir que la JVM necesita reciclar objetos basura en la memoria, pero no es necesario reciclarlos inmediatamente.
Una es que no puede resolver el problema de quedarse sin recursos de memoria y también aumentará el consumo de GC.
2. Composición del área de memoria JVM <BR>Simplemente hable sobre el montón y la pila en Java
Java divide la memoria en dos tipos: una es memoria de pila y la otra es memoria de montón.
1. Las variables de tipo básico y las variables de referencia de objetos definidas en la función se asignan en la memoria de pila de la función;
2. La memoria del montón se utiliza para almacenar objetos y matrices creados por nuevos. Cuando se define una variable en una función (bloque de código), Java asigna espacio de memoria para la variable en la pila. Cuando se excede el alcance de la variable, Java lo hará. libere automáticamente el espacio de memoria asignado para la variable; la memoria asignada en el montón es administrada por el recolector de basura automático de la máquina virtual Java. La ventaja del montón es que el tamaño de la memoria se puede asignar dinámicamente y la vida útil. No es necesario decírselo al compilador con anticipación, porque está en La memoria se asigna dinámicamente en tiempo de ejecución. La desventaja es que la memoria debe asignarse dinámicamente en tiempo de ejecución y la velocidad de acceso es lenta;
La ventaja de la pila es que la velocidad de acceso es más rápida que la del montón. La desventaja es que el tamaño y la vida útil de los datos almacenados en la pila deben ser deterministas e inflexibles.
El montón de Java se divide en tres áreas: nuevo, antiguo y permanente
GC tiene dos hilos:
Los objetos recién creados se asignan al área Nueva. Cuando el área esté llena, el hilo auxiliar del GC los moverá al área Antigua. Cuando el área Antigua también esté llena, el hilo principal del GC se activará para atravesar todos los objetos en. la memoria del montón. El tamaño del área Antigua es igual a Xmx menos -Xmn
Ajuste de la pila de almacenamiento de la pila Java: los parámetros son + UseDefaultStackSize -Xss256K, lo que significa que cada hilo puede solicitar un espacio de pila de 256k. Cada hilo tiene su propia pila.
3. Cómo configurar la memoria virtual en JVM <BR>Consejo: En JVM, si se utiliza el 98% del tiempo para GC y el tamaño del montón disponible es inferior al 2%, se generará este mensaje de excepción.
Consejo: El tamaño máximo del montón no debe exceder el 80% de la memoria física disponible. Generalmente, las opciones -Xms y -Xmx deben configurarse en el mismo valor y -Xmn debe ser 1/4 del valor -Xmx.
Consejo: La memoria inicial asignada por la JVM se especifica mediante -Xms y el valor predeterminado es 1/64 de la memoria física. La memoria máxima asignada por la JVM se especifica mediante -Xmx y el valor predeterminado es 1/4 de la memoria física; memoria.
De forma predeterminada, cuando la memoria del montón libre es inferior al 40%, la JVM aumentará el montón hasta el límite máximo de -Xmx; cuando la memoria del montón libre es superior al 70%, la JVM reducirá el montón hasta el límite mínimo de; -Xms. Por lo tanto, el servidor generalmente establece -Xms y -Xmx en iguales para evitar ajustar el tamaño del montón después de cada GC.
Consejo: Suponiendo que la memoria física es infinita, el valor máximo de la memoria JVM tiene una gran relación con el sistema operativo.
En pocas palabras, aunque un procesador de 32 bits tiene un espacio de memoria controlable de 4 GB, el sistema operativo específico impondrá un límite.
Este límite es generalmente de 2 GB a 3 GB (en términos generales, es de 1,5 G a 2 G en sistemas Windows y de 2 G a 3 G en sistemas Linux), y no habrá límite para procesadores de más de 64 bits.
Nota: Si Xms excede el valor Xmx, o la suma del valor máximo del montón y el valor máximo no montón excede el límite máximo de la memoria física o del sistema operativo, el servidor no se iniciará.
Consejo: establezca NewSize y MaxNewSize para que sean iguales y el tamaño de "nuevo" no debe ser mayor que la mitad del "antiguo". La razón es que si el área anterior no es lo suficientemente grande, el GC "principal" se activará con frecuencia. , lo que reduce en gran medida el rendimiento.
JVM usa -XX: PermSize para establecer el valor inicial de la memoria no dinámica. El valor predeterminado es 1/64 de la memoria física;
El tamaño máximo de memoria no dinámica lo establece XX:MaxPermSize. El valor predeterminado es 1/4 de la memoria física.
Solución: configurar manualmente el tamaño del montón
Modificar TOMCAT_HOME/bin/catalina.bat
Agregue las siguientes líneas encima de "echo "Usando CATALINA_BASE: $CATALINA_BASE"":
JAVA_OPTS="-servidor -Xms800m -Xmx800m -XX:MaxNewSize=256m"
4. Utilice herramientas de verificación de rendimiento para localizar pérdidas de memoria:
La herramienta JProfiler se utiliza principalmente para verificar y rastrear el rendimiento de los sistemas (limitado al desarrollo de Java). JProfiler puede monitorear el funcionamiento y el rendimiento de JVM monitoreando constantemente el uso de la memoria del sistema, la recolección de basura, el estado de ejecución de subprocesos y otros medios en cualquier momento.
1. La memoria del servidor de aplicaciones está ocupada excesivamente durante mucho tiempo. La memoria a menudo está ocupada en un nivel alto y es difícil recuperarla a un nivel bajo.