¿Por qué JDK1.8 abandona la generación permanente [una pieza es suficiente]

JDK8-PermGen abandonado (PermGen) marcó el comienzo de Metaspace (Metaspace)

1. Antecedentes

2. Por qué abandonar la generación permanente (PermGen)

3. Comprensión profunda del metaespacio (Metaspace)

4. Resumen

======== Línea divisoria de texto =====

1. Antecedentes

1.1 ¿Dónde está la generación permanente (PermGen)?

Según la estructura de jvm del hotspot es la siguiente (la pila de la máquina virtual y la pila del método local se combinan):

La imagen de arriba proviene de la red, pero hay un problema: tanto el área de método como el montón son áreas de memoria compartidas por subprocesos.

Sobre el área de método y la generación permanente:

En HotSpot JVM, la generación permanente discutida esta vez es el área de método en la figura anterior (llamada área de método en la especificación de JVM). La "Especificación de máquina virtual de Java" solo estipula el concepto de área de método y su función, pero no estipula cómo implementarlo. No hay generación permanente en otras JVM.
 

1.2 Obsolescencia de la generación permanente JDK8

Los cambios de generación permanente de JDK8 son los siguientes:

1. La nueva generación: Eden + From Survivor + To Survivor

2. Vejez: OldGen

3. Generación permanente (implementación del área de método): PermGen -----> Reemplazar con Metaspace (en la memoria local)

 

 2. Por qué abandonar la generación permanente (PermGen)

 2.1 Instrucciones oficiales

Consulte JEP122: http://openjdk.java.net/jeps/122, el texto original está interceptado:

Motivación

Esto es parte del esfuerzo de convergencia de JRockit y Hotspot. Los clientes de JRockit no necesitan configurar la generación permanente (ya que JRockit no tiene una generación permanente) y están acostumbrados a no configurar la generación permanente.

 Es decir: la eliminación de la generación permanente es un esfuerzo por integrar HotSpot JVM y JRockit VM, porque JRockit no tiene una generación permanente y no se requiere generación permanente.

 2.2 Propenso a problemas en el uso real

Debido a que la memoria de generación permanente a menudo es insuficiente o se producen pérdidas de memoria, la excepción java.lang.OutOfMemoryError: PermGen

3. Conocimiento profundo del Metaspace

3.1 Tamaño de la memoria del metaespacio

Metaspace es la implementación del área de métodos en HotSpot jvm. El área de métodos se utiliza principalmente para almacenar información de clases, grupos de constantes, datos de métodos, códigos de métodos, etc. El área de método es lógicamente parte del montón, pero para distinguirlo del montón, normalmente se le llama "non-heap".

La naturaleza del metaespacio es similar a la de la generación permanente, y ambas son la realización del área de método en la especificación JVM. Sin embargo , la mayor diferencia entre el metaespacio y la generación permanente es que el metaespacio no está en la máquina virtual, sino que usa la memoria local. , Depende teóricamente del tamaño de la memoria virtual de los sistemas de 32 bits / 64 bits. Se puede ver que no es ilimitado y requiere parámetros de configuración.

3.2 Parámetros de configuración comunes

1.MetaspaceSize

El tamaño del Metaspace inicializado controla el umbral de GC que se produce en el metaespacio. Después de GC, aumente o disminuya MetaspaceSize dinámicamente. De forma predeterminada, este valor varía de 12 M a 20 M según la plataforma. Utilice el  comando Java -XX: + PrintFlagsInitial para ver los parámetros de inicialización de la máquina

2.MaxMetaspaceSize

Limite el límite superior del crecimiento de Metaspace para evitar que Metaspace use la memoria local indefinidamente debido a ciertas circunstancias y afecte a otros programas. El valor predeterminado de este parámetro en esta máquina es 4294967295B (aproximadamente 4096 MB).

3.MinMetaspaceFreeRatio

Después de realizar Metaspace GC, se calculará la relación de espacio libre actual de Metaspace. Si la relación de espacio libre es menor que este parámetro (es decir, la relación real de no inactividad es demasiado grande y la memoria no es suficiente), la máquina virtual aumentará el tamaño del Metaspace. El valor predeterminado es 40, que es 40%. La configuración de este parámetro puede controlar la tasa de crecimiento de Metaspace. Un valor demasiado pequeño resultará en un crecimiento lento de Metaspace, y el uso de Metaspace se saturará gradualmente, lo que puede afectar la carga de clases posterior. Un valor demasiado grande hará que Metaspace crezca demasiado rápido y desperdicie memoria.

4.MaxMetasaceFreeRatio

Después de que se realiza Metaspace GC, se calculará la proporción de espacio libre del Metaspace actual. Si la proporción de espacio libre es mayor que este parámetro, la máquina virtual liberará parte del espacio de Metaspace. El valor predeterminado es 70, que es 70%.

5.MaxMetaspaceExpansion

Amplitud máxima cuando crece Metaspace. El valor predeterminado de este parámetro en esta máquina es 5452592B (aproximadamente 5 MB).

6.MinMetaspaceExpansion

La amplitud mínima cuando crece Metaspace. El valor predeterminado de este parámetro en esta máquina es 340784B (aproximadamente 330 KB).

3.3 Probar y rastrear el tamaño del metaespacio

 3.3.1. Constantes de cadena de prueba

import java.util.ArrayList;
import java.util.List;

public class StringTest {
    static String  base = "string";

    public static void main(String[] args) {

        List<String> list = new ArrayList<String>();
        for (int i=0;i< Integer.MAX_VALUE;i++){
            String str = base + base;
            base = str;
            list.add(str.intern());
        }
    }
}

 

 Dado que la memoria máxima se establece en 20 M, pronto se desbordará, como se muestra en la siguiente figura:

 Se puede ver en jdk8:

1. La constante de cadena se transfiere de la generación permanente al montón.

2. La generación persistente ya no existe y se ha eliminado el parámetro PermSize MaxPermSize. (Vea las dos últimas líneas en la imagen)

3.3.2. Probar desbordamiento del metaespacio

Según la definición, probamos el desbordamiento del metaespacio cargando la clase, el código es el siguiente:

1 paquete jdk8; 
 2 
 3 import java.io.File; 
 4 import java.lang.management.ClassLoadingMXBean; 
 5 import java.lang.management.ManagementFactory; 
 6 import java.net.URL; 
 7 import java.net.URLClassLoader; 
 8 import java.util.ArrayList; 
 9 import java.util.List; 
10 
11 / ** 
12 * 
13 * @ClassName: OOMTest 
14 * @Description: Simular el desbordamiento de carga de clase (metaspace oom) 
15 * @author diandian.zhang 
16 * @ fecha 9:45:40 AM, 27 de abril de 2017 
17 * / 
18 public class OOMTest {   
19 public static void main (String [] args) {   
20 try {   
21 // Prepare url  
22 URL url = new File ("D: / 58workplace / 11study / src / main / java / jdk8"). ToURI (). ToURL ();   
23 URL [] urls = {url};   
24 // Obtenga el tipo de carga relevante La interfaz JMX   
25 ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean ();   
26 // Se usa para almacenar en caché los cargadores de clases   
27 List <ClassLoader> classLoaders = new ArrayList <ClassLoader> ();   
28 while (true) {   
29 // Cargar tipos y caché Instancia 
de Class Loader   30 ClassLoader classLoader = new URLClassLoader (urls);   
31 classLoaders.add (classLoader);   
32 classLoader.loadClass ("ClassA");   
33 // Mostrar información de cantidad (el número de tipos que se han cargado en total, que actualmente son válidos Número de tipos, el número de tipos que se han desinstalado)  
34 System.out.println ("total:" + loadingBean.getTotalLoadedClassCount ());  
35 System.out.println ("activo:" + loadingBean.getLoadedClassCount ());  
36 System.out.println ("descargado:" + loadingBean.getUnloadedClassCount ());  
37}   
38} catch (Excepción e) {   
39 e.printStackTrace ();  
40}   
41}   
42}  

Para desbordar rápidamente, configure los parámetros: -XX: MetaspaceSize = 8m -XX: MaxMetaspaceSize = 80m, los resultados de ejecución son los siguientes:

 

 La figura anterior confirma que la carga de clases (la función del área de método) en nuestro JDK8 ya no está en el PerGem permanente, sino en Metaspace. Se puede ver con JVisualVM, que es más intuitivo.

 Cuatro, resumen

Este artículo explica el origen y la esencia de Metaspace, las configuraciones comunes y el monitoreo y las pruebas. El tamaño del metaespacio cambia dinámicamente, pero no es infinito, lo mejor es estar atento al tamaño para no afectar la memoria del servidor.

Supongo que te gusta

Origin blog.csdn.net/sjmz30071360/article/details/89456177
Recomendado
Clasificación