Maison > Java > javaDidacticiel > Analyse du tas, de la pile et du pool constant d'allocation de mémoire en Java

Analyse du tas, de la pile et du pool constant d'allocation de mémoire en Java

巴扎黑
Libérer: 2017-08-01 10:56:35
original
1563 Les gens l'ont consulté

L'allocation de mémoire Java comprend principalement les zones suivantes :

1 Registre : nous ne pouvons pas le contrôler dans le programme

2. Pile : stocke les types de données de base et les références d'objets, mais la pile. l'objet lui-même n'est pas stocké sur la pile, mais est stocké dans le tas

3. Heap : stocke les données générées avec le nouveau

4. Domaine statique : stocké dans l'objet défini avec static Member<.>

5. Pool constant : stocker les constantes

6. Stockage non RAM (mémoire vive) : espace de stockage permanent tel que le disque dur

******* ************************************************** * ********

Pile dans l'allocation de mémoire Java

Quelques

types de base définis dans les fonctions Les données variables et la variable de référence de l'objet sont allouées dans la mémoire pile de la fonction. Lorsqu'une variable est définie dans un bloc de code, Java alloue de l'espace mémoire pour la variable sur la pile. Lorsque la variable quitte la portée, Java libère automatiquement l'espace mémoire alloué à la variable et l'espace mémoire peut être utilisé immédiatement. être utilisé à d’autres fins.

Tas dans l'allocation de mémoire Java

La mémoire tas est utilisée pour stocker les objets créés par

new et array . La mémoire allouée dans le tas est gérée par le garbage collector automatique de la machine virtuelle Java.

Après avoir généré un tableau ou un objet dans le tas, vous pouvez également définir une variable spéciale dans la pile, afin que la valeur de cette variable dans la pile soit égale à la première adresse du tableau ou de l'objet dans le mémoire tas. Cette variable devient une variable de référence du tableau ou de l'objet. Une variable de référence équivaut à donner un nom à un tableau ou un objet. Vous pouvez ensuite utiliser la variable de référence dans la pile pour accéder au tableau ou à l'objet dans le tas du programme. Une variable de référence équivaut à donner un nom à un tableau ou un objet.

Les variables de référence sont des variables ordinaires qui sont allouées sur la pile lorsqu'elles sont définies. Les variables de référence sont libérées une fois que le programme s'exécute en dehors de sa portée. Les tableaux et les objets eux-mêmes sont alloués dans le tas Même si le programme s'exécute en dehors du bloc de code où se trouve l'instruction utilisant new pour générer le tableau ou l'objet, la mémoire occupée par le tableau et l'objet lui-même ne sera pas libérée. les objets n'ont pas de variables de référence pointant vers eux, ils deviennent des déchets et ne peuvent plus être utilisés, mais ils occupent toujours l'espace mémoire et seront collectés (libérés) par le garbage collector à un moment indéterminé plus tard. C'est aussi la raison pour laquelle Java occupe plus de mémoire.

 

En fait, les variables de la pile pointent vers des variables dans la mémoire tas. C'est un pointeur en Java !

Pool constant (pool constant)

Le pool constant fait référence au pool qui est déterminé lors de la compilation et est enregistré dans le fichier compilé. Certaines données dans le fichier .class. En plus des

valeurs constantes (finales)types de base (tels que int, long, etc.) et types d'objets (tels que String et array) défini dans le code 🎜> contient également quelques références de symboles sous forme de texte, telles que :

    Noms complets de classes et d'interfaces
  1. Noms des champs et descripteurs
  2. méthodes et noms et descripteurs.
  3. La machine virtuelle doit maintenir un pool constant pour chaque type chargé. Le pool de constantes est un ensemble ordonné de constantes utilisées par ce type, y compris des constantes directes (constantes de chaîne, entières et à virgule flottante) et des références symboliques à d'autres types, champs et méthodes.
Pour les constantes String, leurs valeurs sont dans le pool de constantes. Le pool de constantes dans la JVM existe sous la forme d'une table en mémoire. Pour le type String, il existe une table CONSTANT_String_info de longueur fixe utilisée pour stocker les valeurs de chaîne littérale. Remarque : Cette table stocke uniquement les valeurs de chaîne littérale, pas les symboles. . Cela dit, vous devez avoir une compréhension claire de l'emplacement de stockage des valeurs de chaîne dans le pool constant.

 

Lorsque le programme est exécuté, le pool de constantes sera stocké dans la zone de méthode au lieu du tas.

Tas et pile

Le tas Java est une zone de données d'exécution à partir de laquelle la classe (objets) alloue de l'espace à ces objets créés. grâce à des instructions telles que new, newarray, anewarray et multianewarray, elles ne nécessitent pas que le code du programme soit explicitement libéré Le tas est responsable du garbage collection

L'avantage du tas est qu'il peut allouer dynamiquement de la mémoire. La taille

et la durée de vie n'ont pas besoin d'être indiquées au compilateur à l'avance, car il alloue dynamiquement de la mémoire au moment de l'exécution, et le garbage collector de Java collectera automatiquement ces données qui ne sont plus utilisées. Mais l'inconvénient est. . , en raison de la nécessité d'allouer dynamiquement de la mémoire au moment de l'exécution, la vitesse d'accès est plus lente .

 L'avantage de la pile est que la vitesse d'accès est plus rapide que celle du tas, juste derrière le registre, et la pileles données peuvent être partagées. Mais l'inconvénient est qu'il faut déterminer la taille et la durée de vie des données stockées dans la pile , ce qui manque de flexibilité. La pile stocke principalement certains types de données variables de base (int, short, long, byte, float, double, boolean, char) et des descripteurs d'objet (références).

********************************************* **** *************************

Ici on s'intéresse principalement au stack, au tas et pool constant. Pour la pile, les objets du pool constant peuvent être partagés , mais les objets du tas ne peuvent pas être partagés . La taille et le cycle de vie des données dans la pile peuvent être déterminés. Lorsqu'il n'y a aucune référence aux données, les données disparaissent. Les objets du tas sont recyclés par le garbage collector, donc la taille et le cycle de vie n'ont pas besoin d'être déterminés, et il y a une grande flexibilité.

Allocation de mémoire de chaîne :

Pour les chaînes, les références à leurs

objets sont stockées dans la pile , S'il a été créé lors de la compilation (directement défini avec des guillemets doubles), il sera stocké dans le pool de constantes. S'il est déterminé lors de l'exécution (nouveau), il sera stocké dans le tas . Pour les chaînes égales à equals, il n'y a toujours qu'une seule copie dans le pool constant et plusieurs copies de dans le tas.

Comme le code suivant :


        String s1 = "china";
        String s2 = "china";
        String s3 = "china";

        String ss1 = new String("china");
        String ss2 = new String("china");
        String ss3 = new String("china");
Copier après la connexion

Voici une explication des trois flèches jaunes, qui sont générés par new Lorsqu'une chaîne (supposée être "china"), il vérifiera d'abord s'il existe déjà un objet "china" dans le pool constant. Sinon, créera un objet chaîne dans le pool constant, puis en créera un autre. pool constant dans le tas. L'objet de copie de cet objet "china".

C'est aussi une question d'entretien : Strings=newString("xyz"); Combien d'objets sont générés ? Un ou deux, s'il n'y a pas de "xyz" dans le pool constant, c'est deux.

Le pool de constantes qui existe dans le fichier .class est chargé par la JVM pendant l'exécution et peut être étendu. La méthode intern() de String est une méthode pour étendre le pool de constantes ; lorsqu'une instance String str appelle la méthode intern(), Java vérifie s'il existe une constante de chaîne avec le même Unicode dans le pool de constantes. Si tel est le cas, elle renvoie. sa référence. Si sinon, ajoutez une chaîne Unicode égale à str dans le pool de constantes et renvoyez sa référence

comme suit :


        String s0= "kvill";   
        String s1=new String("kvill");   
        String s2=new String("kvill");   
        System.out.println( s0==s1 );     
        s1.intern();   
        s2=s2.intern(); //把常量池中"kvill"的引用赋给s2   
        System.out.println( s0==s1);   
        System.out.println( s0==s1.intern() );   
        System.out.println( s0==s2 );
Copier après la connexion
Sortie. résultat :

faux
faux
vrai
vrai

String Plusieurs exemples de problèmes de pool constants :


【1】
String a = "ab"= "b"= "a" +== b)); = "ab" String bb = "b"= "a" +== b)); = "ab" String bb == "a" +== b));   "b"
Copier après la connexion
Analyse :

 [1], JVM a des références de chaîne, car dans la chaîne Dans le Connexion "+", il existe une référence de chaîne et la valeur de la référence ne peut pas être déterminée lors de la compilation du programme, c'est-à-dire que "a" + bb ne peut pas être optimisé par le compilateur. Il ne peut être alloué et connecté dynamiquement que pendant l'exécution du programme. La nouvelle adresse est attribuée à b. Le résultat du programme ci-dessus est donc faux.

La seule différence entre [2] et [1] est que la chaîne bb est modifiée de manière finale. Pour la variable finale modifiée, elle est analysée dans une copie locale de la valeur constante au moment de la compilation et stockée dans celle-ci. propre constante. Regroupée ou intégrée dans son flux de bytecode. Ainsi, l’effet de « a » + bb et « a » + « b » à ce moment est le même. Le résultat du programme ci-dessus est donc vrai.

[3] La JVM ne peut pas déterminer la valeur de la chaîne de référence bb lors de la compilation. Ce n'est qu'après l'appel de la méthode pendant l'exécution du programme que la valeur de retour de la méthode et "a" sont connectées dynamiquement et que l'adresse est. alloué b, donc le résultat du programme ci-dessus est faux.

Conclusion :

String est une classe d'emballage spéciale, sa référence est stockée sur la pile, et le contenu de l'objet doit être déterminé en fonction de la méthode de création (pool constant et Heap). Certains sont créés lors de la compilation et stockés dans le pool de constantes de chaîne, tandis que d'autres sont créés au moment de l'exécution. Utilisez le nouveau mot-clé et stockez-les dans le tas.

Allocation de variables et constantes de types de base en mémoire

Pour les variables et constantes de types de base, les variables et les références sont stockées Sur la pile, les constantes sont stockées dans un pool de constantes.

Comme le code suivant :


        int i1 = 9;        int i2 = 9;        int i3 = 9;        final int INT1 = 9;        final int INT2 = 9;        final int INT3 = 9;
Copier après la connexion

  编译器先处理int i1 = 9;首先它会在栈中创建一个变量为i1的引用,然后查找栈中是否有9这个值,如果没找到,就将9存放进来,然后将i1指向9。接着处理int i2 = 9;在创建完i2的引用变量后,因为在栈中已经有9这个值,便将i2直接指向9。这样,就出现了i1与i2同时均指向9的情况。最后i3也指向这个9。

成员变量和局部变量在内存中的分配

  对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。 形式参数是局部变量,局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。 成员变量存储在堆中的对象里面,由垃圾回收器负责回收。   如以下代码:


class BirthDate {    private int day;    private int month;    private int year;    public BirthDate(int d, int m, int y) {
        day = d;
        month = m;
        year = y;
    }    // 省略get,set方法………}public class Test {    public static void main(String args[]) {        int date = 9;
        Test test = new Test();
        test.change(date);
        BirthDate d1 = new BirthDate(7, 7, 1970);
    }    public void change(int i) {
        i = 1234;
    }
}
Copier après la connexion

  对于以上这段代码,date为局部变量,i,d,m,y都是形参为局部变量,day,month,year为成员变量。下面分析一下代码执行时候的变化:    

  1. main方法开始执行:int date = 9; date局部变量,基础类型,引用和值都存在栈中。

  2. Test test = new Test();test为对象引用,存在栈中,对象(new Test())存在堆中。 

  3. test.change(date);  i为局部变量,引用和值存在栈中。当方法change执行完成后,i就会从栈中消失。

  4. BirthDate d1= new BirthDate(7,7,1970); d1为对象引用,存在栈中,对象(new BirthDate())存在堆中,其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中。day,month,year为成员变量,它们存储在堆中(new BirthDate()里面)。当BirthDate构造方法执行完之后,d,m,y将从栈中消失。 

  5. main方法执行完之后,date变量,test,d1引用将从栈中消失,new Test(), new BirthDate()将等待垃圾回收。

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal