Maison  >  Article  >  Java  >  Introduction détaillée à la zone mémoire Java et à l'exception de débordement de mémoire

Introduction détaillée à la zone mémoire Java et à l'exception de débordement de mémoire

零下一度
零下一度original
2017-06-25 10:58:351387parcourir

Zone mémoire Java et exception de débordement de mémoire

1. Zone de données d'exécution

 

 1. Compteur de programme : thread privé, utilisé pour stocker l'emplacement de l'instruction actuellement exécutée

2. Pile de machine virtuelle Java : thread privé, décrivant le modèle d'exécution de la méthode Java ; lors de l'exécution d'une méthode, un cadre de pile sera créé pour stocker les variables locales et les variables de type de base ; . Référence et autres informations

3. Pile de méthodes natives Java : thread privé, servant les méthodes natives utilisées par la machine virtuelle

4. Tas Java : thread partagé, est le principal lieu de travail de le garbage collector ;Instances d'objets de stockage, etc.

5. Zone de méthode : partage de threads ; informations sur la classe de stockage, constantes, variables statiques, etc.

  Constantes d'exécution : stockez divers littéraux et références de symboles. généré lors de la compilation

6. Mémoire directe : mémoire machine

2. Objet machine virtuelle

1. Création d'objet

  • Vérifiez d'abord Le pool de constantes peut-il localiser la référence symbolique de cette classe et vérifier si la classe a été chargée et initialisée, sinon le processus de chargement doit être effectué en premier

  • Allouer de la mémoire pour l'objet ; : calculez l'espace et extrayez-le du tas Divisez une zone continue ou discontinue ; utilisez cas+failure retry pour éviter les problèmes de sécurité des threads (car les objets sont créés très fréquemment, je ne sais pas si la mémoire actuelle a été allouée)

  • Initialiser l'espace mémoire : Initialiser l'espace mémoire alloué à la valeur 0

  • Définir les informations de base de l'objet : métadonnées, code de hachage, gc, etc.

  • Exécuter l'initialisation init de Java :

2. Disposition de la mémoire de l'objet

En-tête de l'objet : stocke le code de hachage, état de verrouillage, etc. et type pointeur de l'objet (la classe pointée par l'objet) Métadonnées)

Données d'instance : les informations réellement stockées par l'objet

Remplissage d'alignement : le remplissage est conforme à les règles

3. Accès au positionnement de l'objet

Accès à l'objet, via les données de référence sur la pile Java, il maintient une référence à l'objet

Méthodes d'accès : handle et accès direct

Handle : Un pool de handles est maintenu dans le tas, et la référence pointe vers le handle. informations sur les données d'instance d'objet et les données de type

Il est facile à déplacer, il suffit de modifier les données d'instance directement dans le handle ; la surcharge est élevée et il existe de nombreux positionnements de pointeurs uniques

 

Direct : référence directement à l'adresse de l'objet

Vitesse rapide

3. Combat réel OutofMemoryERROR

1 Débordement de tas .java

 Paramètres : -Valeur minimale du tas Xms ; -Valeur maximale du tas Xmx ; -XX :+HeapDumpOnOutOfMemoryError Analyse de l'instantané de mémoire en cas de débordement

  Objets de stockage du tas : un grand nombre de des objets peuvent être créés pour obtenir un débordement de tas : espace de tas

2. Débordement de pile

La profondeur de pile peut être obtenue en augmentant la profondeur de pile grâce à une récursivité infinie ou en créant un grand nombre de threads

 3. Zone de méthode et débordement de pool constant
//递归来StackOverFlowerpublic class JavaVMStackSOF {private int stackLength = 1;public void stackLeak(){
        stackLength++;
        stackLeak();
    }public static void main(String[] args)throws Throwable{
        JavaVMStackSOF oom = new JavaVMStackSOF();try {
            oom.stackLeak();
        } catch(Throwable e){
            System.out.println("stack length:" + oom.stackLength);throw e;
        }
    }
}
 
Paramètres

 : -XX : Taille de la zone de méthode PermSize -XX : Taille maximale de la méthode MaxPermSize ; zone

  Avant JDK1.6, vous pouviez créer un grand nombre de chaînes et la machine virtuelle copiait les objets dans le pool constant

.  

En 1.7 et versions ultérieures, cela n'est pas possible, car la machine virtuelle ne sauvegardera la référence à l'objet que lorsque cet objet apparaîtra pour la première fois dans le pool de constantes

Débordement de la méthode zone : La zone de méthode enregistre les informations de classe et les débordements en générant un grand nombre de classes dynamiques. Par exemple, spring génère en fait des classes via des proxys dynamiques

public class JavaMethodAreaOOM{public static void main(String[]args){while(true){//创建大量的动态类,动态代理OOMObjectEnhancer enhancer=new Enhancer();
            enhancer.setSuperclass(OOMObject.class);
            enhancer.setUseCache(false);
            enhancer.setCallback(new MethodInterceptor(){public Object intercept(Object obj,Method method,Object[]args,MethodProxy proxy)throws Throwable{return proxy.invokeSuper(obj,args);
                }}
            );
            enhancer.create();
        }}static class OOMObject{
    }
}
. String.intern() est une méthode Native. Sa fonction est : si le pool de constantes chaîne contient déjà une chaîne égale à cet objet String, renvoie la chaîne représentant cette chaîne dans l'objet String ; Objet String au pool constant, et renvoie une référence à cet objet String

JDK6 et avant : la zone méthode (génération permanente) est séparée, et le pool constante est dans Dans la zone méthode

JDK7 : Passer à la génération permanente

Lorsque ce code est exécuté dans le JDK 1.6, il obtiendra deux faux, mais lorsqu'il est exécuté dans le JDK 1.7, il obtiendra un vrai et un faux.

La raison de la différence est la suivante : dans JDK 1.6, la méthode intern() copiera la première instance de chaîne rencontrée dans la génération permanente, et renverra une référence à l'instance de chaîne dans la génération permanente, et la chaîne L'instance créée par StringBuilder se trouve sur le tas Java, il ne doit donc pas s'agir de la même référence et false sera renvoyé.

Et JDK 1.7 : l'implémentation d'intern() ne copiera plus l'instance, mais enregistrera uniquement la référence d'instance de la première occurrence de dans le pool de constantes, donc la référence renvoyée par intern() est la identique à celle créée par StringBuilder. Cette instance de chaîne est la même.

La comparaison de str2 renvoie false car la chaîne "java" est déjà apparue avant l'exécution de StringBuilder.toString(), et il y a déjà une référence à celle-ci dans le pool de constantes de chaîne, ce qui ne répond pas aux exigences de principe de la « première occurrence », et la chaîne « logiciel informatique » apparaît pour la première fois, donc true est renvoyée

 

Remarque : 1.7 et versions ultérieures enregistrent la référence qui apparaît pour la première fois ; analyse

4. Mémoire directe native

Paramètres : -XX : taille de la mémoire directe MaxDirectMemorySize ; par défaut == mémoire de tas maximale

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn