Pourquoi JDK1.8 abandonne-t-il la génération permanente [une seule pièce suffit]

PermGen abandonné par JDK8 (PermGen) a inauguré Metaspace (Metaspace)

1. Origines

2. Pourquoi abandonner la génération permanente (PermGen)

3. Compréhension approfondie de metaspace (Metaspace)

4. Résumé

======== Ligne de séparation du texte =====

1. Origines

1.1 Où est la génération permanente (PermGen)?

Selon la structure jvm hotspot est la suivante (la pile de machine virtuelle et la pile de méthodes locales sont combinées):

L'image ci-dessus est tirée du réseau, mais il y a un problème: la zone de méthode et le tas de tas sont des zones de mémoire partagées par les threads.

À propos de la zone de méthode et de la génération permanente:

Dans HotSpot JVM, la génération permanente discutée cette fois est la zone de méthode dans la figure ci-dessus (appelée zone de méthode dans la spécification JVM). La "Spécification de la machine virtuelle Java" stipule uniquement le concept de zone de méthode et sa fonction, mais ne précise pas comment l'implémenter. Il n'y a pas de génération permanente sur les autres JVM.
 

1.2 Obsolescence de la génération permanente JDK8

Les changements de génération permanents JDK8 sont les suivants:

1. La nouvelle génération: Eden + From Survivor + To Survivor

2. Vieillesse: OldGen

3. Génération permanente (implémentation de la zone de méthode): PermGen -----> Remplacer par Metaspace (en mémoire locale)

 

 2. Pourquoi abandonner la génération permanente (PermGen)

 2.1 Instructions officielles

Reportez-vous à JEP122: http://openjdk.java.net/jeps/122, le texte original est intercepté:

Motivation

Cela fait partie de l'effort de convergence JRockit et Hotspot. Les clients de JRockit n'ont pas besoin de configurer la génération permanente (puisque JRockit n'a pas de génération permanente) et sont habitués à ne pas configurer la génération permanente.

 Autrement dit: la suppression de la génération permanente est un effort pour intégrer HotSpot JVM et JRockit VM, car JRockit n'a pas de génération permanente et il n'est pas nécessaire de configurer une génération permanente.

 2.2 Sujettes à des problèmes lors de l'utilisation réelle

Étant donné que la mémoire de génération permanente est souvent insuffisante ou que des fuites de mémoire se produisent, l'exception java.lang.OutOfMemoryError: PermGen

3. Compréhension approfondie de Metaspace

3.1 Taille de la mémoire du méta-espace

Metaspace est l'implémentation de la zone de méthode dans HotSpot jvm. La zone de méthode est principalement utilisée pour stocker les informations de classe, les pools de constantes, les données de méthode, les codes de méthode, etc. La zone de méthode fait logiquement partie du tas, mais pour la distinguer du tas, elle est généralement appelée "non-tas".

La nature de la métaspace est similaire à celle de la génération permanente, et les deux sont la réalisation de la zone de méthode dans la spécification JVM. Cependant , la plus grande différence entre métaspace et génération permanente est que métaspace n'est pas dans la machine virtuelle, mais utilise la mémoire locale. , En théorie, dépend de la taille de la mémoire virtuelle du système 32 bits / 64 bits. On voit qu'il n'est pas illimité et nécessite des paramètres de configuration.

3.2 Paramètres de configuration communs

1.MetaspaceSize

La taille du Metaspace initialisé contrôle le seuil de GC qui se produit dans le Metaspace. Après GC, augmentez ou diminuez le MetaspaceSize dynamiquement. Par défaut, cette valeur varie de 12M à 20M selon la plateforme. Utilisez la commande Java  -XX: + PrintFlagsInitial pour afficher les paramètres d'initialisation de la machine

2.MaxMetaspaceSize

Limitez la limite supérieure de croissance de Metaspace pour empêcher Metaspace d'utiliser indéfiniment la mémoire locale en raison de certaines circonstances et affectant d'autres programmes. La valeur par défaut de ce paramètre sur cette machine est 4294967295B (environ 4096 Mo).

3.MinMetaspaceFreeRatio

Une fois Metaspace GC effectué, le taux d'espace libre actuel de Metaspace sera calculé. Si le taux d'espace libre est inférieur à ce paramètre (c'est-à-dire que le taux de non-inactivité réel est trop grand et que la mémoire n'est pas suffisante), la machine virtuelle augmentera la taille de Metaspace. La valeur par défaut est 40, soit 40%. La définition de ce paramètre peut contrôler le taux de croissance de Metaspace. Une valeur trop petite entraînera une croissance lente de Metaspace, et l'utilisation de Metaspace deviendra progressivement saturée, ce qui peut affecter le chargement de classe ultérieur. Une valeur trop élevée entraînera une croissance trop rapide de Metaspace et une perte de mémoire.

4.MaxMetasaceFreeRatio

Une fois Metaspace GC effectué, le taux d'espace libre du Metaspace actuel sera calculé. Si le taux d'espace libre est supérieur à ce paramètre, la machine virtuelle libère une partie de l'espace Metaspace. La valeur par défaut est 70, soit 70%.

5.MaxMetaspaceExpansion

Amplitude maximale lorsque Metaspace se développe. La valeur par défaut de ce paramètre sur cette machine est 5452592B (environ 5 Mo).

6.MinMetaspaceExpansion

L'amplitude minimale lorsque Metaspace se développe. La valeur par défaut de ce paramètre sur cette machine est 340784B (environ 330 Ko).

3.3 Tester et suivre la taille du méta-espace

 3.3.1. Constantes de chaîne de test

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());
        }
    }
}

 

 La mémoire maximale étant définie sur 20 Mo, elle débordera bientôt, comme indiqué dans la figure suivante:

 Il peut être vu dans jdk8:

1. La constante de chaîne est transférée de la génération permanente vers le tas.

2. La génération persistante n'existe plus et le paramètre PermSize MaxPermSize a été supprimé. (Voir les deux dernières lignes de l'image)

3.3.2. Tester le débordement du méta-espace

Selon la définition, nous testons le débordement de métaspace en chargeant la classe, le code est le suivant:

1 package 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: Simule un débordement de chargement de classe (metaspace oom) 
15 * @author diandian.zhang 
16 * @date 9:45:40 AM, 27 avril 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 // Chargement du type pertinent L'interface JMX   
25 ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean ();   
26 // Utilisé pour mettre en cache les chargeurs de classes   
27 List <ClassLoader> classLoaders = new ArrayList <ClassLoader> ();   
28 while (true) {   
29 // Charger les types et le cache Class Loader instance   
30 ClassLoader classLoader = new URLClassLoader (urls);   
31 classLoaders.add (classLoader);   
32 classLoader.loadClass ("ClassA");   
33 // Affiche les informations de quantité (le nombre de types qui ont été chargés au total, qui sont actuellement valides Nombre de types, le nombre de types qui ont été désinstallés)  
34 System.out.println ("total:" + loadingBean.getTotalLoadedClassCount ());  
35 System.out.println ("actif:" + loadingBean.getLoadedClassCount ());  
36 System.out.println ("déchargé:" + loadingBean.getUnloadedClassCount ());  
37}   
38} catch (Exception e) {   
39 e.printStackTrace ();  
40}   
41}   
42}  

Afin de déborder rapidement, définissez les paramètres: -XX: MetaspaceSize = 8m -XX: MaxMetaspaceSize = 80m, les résultats en cours d'exécution sont les suivants:

 

 La figure ci-dessus confirme que le chargement de classe (la fonction de la zone de méthode) dans notre JDK8 n'est plus dans le PerGem permanent, mais dans Metaspace. On peut le voir avec JVisualVM, qui est plus intuitif.

 Quatre, résumé

Cet article explique l'origine et l'essence de Metaspace, les configurations courantes, ainsi que la surveillance et les tests. La taille du méta-espace change dynamiquement, mais elle n'est pas infinie, il est préférable de garder un œil sur la taille pour ne pas affecter la mémoire du serveur.

Je suppose que tu aimes

Origine blog.csdn.net/sjmz30071360/article/details/89456177
conseillé
Classement