Mémoire de pile et espace de pile en Java

Mémoire de pile et espace de pile en Java

1. introduction

Pour exécuter une application de manière optimale, JVM divise la mémoire en pile et en pile. Whenever we declare new variables and objects, call new method, declare a String or perform similar operations, JVM designates memory to these operations from either Stack Memory or Heap Space.

Dans ce didacticiel, nous aborderons ces modèles de mémoire. Nous allons énumérer quelques différences clés entre eux, comment ils sont stockés dans la RAM, les fonctionnalités qu'ils offrent et où les utiliser.

2. Mémoire de pile en Java

Stack Memory in Java is used for static memory allocation and the execution of a thread. Il contient des valeurs primitives spécifiques à une méthode et des références aux objets qui se trouvent dans un tas, référencés à partir de la méthode.

L’accès à cette mémoire se fait dans l’ordre LIFO (dernier entré, premier sorti). Chaque fois qu'une nouvelle méthode est appelée, un nouveau bloc situé au-dessus de la pile est créé. Il contient des valeurs spécifiques à cette méthode, telles que des variables primitives et des références à des objets.

Lorsque la méthode termine son exécution, le cadre de pile correspondant est vidé, le flux retourne à la méthode d'appel et l'espace devient disponible pour la méthode suivante.

2.1. Principales caractéristiques de la mémoire de pile

Outre ce que nous avons discuté jusqu'à présent, voici quelques autres caractéristiques de la mémoire de pile:

  • Il grossit et diminue à mesure que de nouvelles méthodes sont appelées et retournées respectivement

  • Les variables de la pile n'existent que tant que la méthode qui les a créées est en cours d'exécution

  • Il est automatiquement alloué et désalloué lorsque la méthode termine l'exécution

  • Si cette mémoire est pleine, Java renvoiejava.lang.StackOverFlowError

  • L'accès à cette mémoire est rapide par rapport à la mémoire heap

  • Cette mémoire est threadsafe car chaque thread fonctionne dans sa propre pile

3. Heap Space à Java

Heap space in Java is used for dynamic memory allocation for Java objects and JRE classes at the runtime. Les nouveaux objets sont toujours créés dans l'espace de mémoire et les références à ces objets sont stockées dans la mémoire de la pile.

Ces objets ont un accès global et sont accessibles de n’importe où dans l’application.

Ce modèle de mémoire est ensuite divisé en parties plus petites appelées générations.

  1. Young Generation – c'est ici que tous les nouveaux objets sont alloués et vieillis. Un ramassage mineur des ordures se produit quand il se remplit

  2. Old or Tenured Generation – c'est là que les objets survivants sont stockés. Lorsque des objets sont stockés dans la jeune génération, un seuil d’âge est défini et lorsque ce seuil est atteint, l’objet est déplacé vers l’ancienne génération.

  3. Permanent Generation – il s'agit de métadonnées JVM pour les classes d'exécution et les méthodes d'application

Ces différentes parties sont également abordées dans cet article -Difference Between JVM, JRE, and JDK.

Nous pouvons toujours manipuler la taille de la mémoire de tas selon nos besoins. Pour plus d'informations, visitez celinked example article.

3.1. Principales caractéristiques de la mémoire Java Heap

Outre ce que nous avons discuté jusqu'à présent, voici quelques autres caractéristiques de l'espace de tas:

  • Il est accessible via des techniques complexes de gestion de la mémoire qui incluent la génération jeune, ancienne ou permanente et la génération permanente

  • Si l'espace du tas est plein, Java renvoiejava.lang.OutOfMemoryError

  • L'accès à cette mémoire est relativement plus lent que la mémoire de pile

  • Cette mémoire, contrairement à stack, n’est pas automatiquement désallouée. Garbage Collector est nécessaire pour libérer les objets inutilisés afin de conserver l'efficacité de l'utilisation de la mémoire

  • Contrairement à la pile, un tas n’est pas threadsafe et doit être protégé en synchronisant correctement le code

4. Exemple

Sur la base de ce que nous avons appris jusqu'à présent, analysons un code Java simple et évaluons comment la mémoire est gérée ici:

class Person {
    int pid;
    String name;

    // constructor, setters/getters
}

public class Driver {
    public static void main(String[] args) {
        int id = 23;
        String pName = "Jon";
        Person p = null;
        p = new Person(id, pName);
    }
}

Analysons cette étape par étape:

  1. En entrant dans la méthodemain(), un espace dans la mémoire de la pile serait créé pour stocker les primitives et les références de cette méthode

    • La valeur primitive de l'entierid sera stockée directement dans la mémoire de la pile

    • La variable de référenceof typePerson will également être créée dans la mémoire de la pile qui pointera vers l'objet réel dans le tas

  2. L'appel au constructeur paramétréPerson(int, String) depuismain() allouera plus de mémoire au-dessus de la pile précédente. Cela va stocker:

    • La référence d'objetthis de l'objet appelant dans la mémoire de la pile

    • La valeur primitiveid dans la mémoire de la pile

    • La variable de référence de l'argumentStringpersonName qui pointera vers la chaîne réelle du pool de chaînes dans la mémoire du tas

  3. Ce constructeur par défaut appelle en outre la méthodesetPersonName(), pour laquelle une allocation supplémentaire aura lieu dans la mémoire de la pile en plus de la précédente. Cela permettra à nouveau de stocker les variables de la manière décrite ci-dessus.

  4. Cependant, pour l'objet nouvellement crééof typePerson, toutes les variables d'instance seront stockées dans la mémoire du tas.

Cette allocation est expliquée dans ce diagramme:

image

5. Sommaire

Avant de conclure cet article, résumons rapidement les différences entre la mémoire de pile et l'espace de tas:

Paramètre Mémoire de pile Espace de tas

Application

La pile est utilisée par parties, une à la fois lors de l'exécution d'un thread

L'application entière utilise l'espace du tas pendant l'exécution

Size

La pile a des limites de taille en fonction du système d'exploitation et est généralement plus petite que Heap

Il n'y a pas de limite de taille sur le tas

Espace de rangement

Stocke uniquement les variables primitives et les références aux objets créés dans Heap Space

Tous les objets nouvellement créés sont stockés ici

Commande

Il est accessible à l'aide du système d'allocation de mémoire Last-in First-out (LIFO)

Cette mémoire est accessible via des techniques complexes de gestion de la mémoire qui incluent la jeune génération, l'ancienne ou la génération permanente et la génération permanente.

Life

La mémoire de pile n'existe que tant que la méthode actuelle est en cours d'exécution

L'espace de tas existe tant que l'application s'exécute

Efficacité

Comparativement beaucoup plus rapide à allouer par rapport au tas

Plus lent à allouer que la pile

Allocation/Deallocation

Cette mémoire est automatiquement allouée et désallouée lorsqu'une méthode est appelée et renvoyée respectivement

L'espace de tas est alloué lorsque de nouveaux objets sont créés et désalloués par Gargabe Collector lorsqu'ils ne sont plus référencés

6. Conclusion

La pile et le tas sont deux manières pour Java d'allouer de la mémoire. Dans cet article, nous avons compris comment ils fonctionnent et à quel moment les utiliser pour développer de meilleurs programmes Java.

Pour en savoir plus sur la gestion de la mémoire en Java, jetez un œil àthis article here. Nous avons également discuté du JVM Garbage Collector qui est brièvement abordéover in this article.