Espace de tas Java vs Pile – Allocation de mémoire en Java

Il y a quelque temps, j’ai écrit quelques articles sur la Collecte des Déchets Java et sur le fait que Java passe par valeur. Après cela, j’ai reçu beaucoup d’e-mails demandant des explications sur l’Espace de Mémoire Java Heap, la Mémoire de Pile Java, l’Allocation de Mémoire en Java et quelles sont les différences entre eux. Vous verrez beaucoup de références à la mémoire de tas et de pile dans les livres et tutoriels Java, mais rarement une explication complète de ce qu’est la mémoire de tas et de pile en termes de programme.

L’Espace de Mémoire Java Heap

L’espace de mémoire Heap Java est utilisé par l’exécution Java pour allouer de la mémoire aux objets et aux classes JRE. Chaque fois que nous créons un objet, il est toujours créé dans l’espace de tas. La collecte des déchets s’exécute sur la mémoire de tas pour libérer la mémoire utilisée par les objets qui n’ont aucune référence. Tout objet créé dans l’espace de tas a un accès global et peut être référencé de n’importe où dans l’application.

La Mémoire de Pile Java

La mémoire de la pile Java est utilisée pour l’exécution d’un thread. Elle contient des valeurs spécifiques à la méthode qui sont de courte durée de vie et des références à d’autres objets dans le tas qui sont référencés par la méthode. La mémoire de la pile est toujours référencée selon l’ordre LIFO (Last-In-First-Out). Chaque fois qu’une méthode est invoquée, un nouveau bloc est créé dans la mémoire de la pile pour la méthode afin de contenir des valeurs primitives locales et des références à d’autres objets dans la méthode. Dès que la méthode se termine, le bloc devient inutilisé et est disponible pour la méthode suivante. La taille de la mémoire de la pile est très petite par rapport à la mémoire du tas.

Heap et Stack Memory dans un programme Java

Comprenons l’utilisation de la mémoire du tas et de la pile avec un programme simple.

package com.journaldev.test;

public class Memory {

	public static void main(String[] args) { // Line 1
		int i=1; // Line 2
		Object obj = new Object(); // Line 3
		Memory mem = new Memory(); // Line 4
		mem.foo(obj); // Line 5
	} // Line 9

	private void foo(Object param) { // Line 6
		String str = param.toString(); //// Line 7
		System.out.println(str);
	} // Line 8

}

L’image ci-dessous montre la mémoire de la pile et du tas en référence au programme ci-dessus et comment elles sont utilisées pour stocker des variables primitives, des objets et des variables de référence. Parcourons les étapes de l’exécution du programme.

  • Dès que nous exécutons le programme, il charge toutes les classes Runtime dans l’espace du tas. Lorsque la méthode main() est trouvée à la ligne 1, Java Runtime crée de la mémoire de la pile à utiliser par le thread de la méthode main().
  • Nous créons une variable locale primitive à la ligne 2, donc elle est créée et stockée dans la mémoire de la pile de la méthode main().
  • Comme nous créons un objet à la 3e ligne, il est créé dans la mémoire heap et la mémoire de la pile contient la référence pour celui-ci. Un processus similaire se produit lorsque nous créons un objet Memory à la 4e ligne.
  • Maintenant, lorsque nous appelons la méthode foo() à la 5e ligne, un bloc en haut de la pile est créé pour être utilisé par la méthode foo(). Comme Java est pass-by-value, une nouvelle référence à l’objet est créée dans le bloc de pile foo() à la 6e ligne.
  • A string is created in the 7th line, it goes in the String Pool in the heap space and a reference is created in the foo() stack space for it.
  • La méthode foo() se termine à la 8e ligne, à ce moment le bloc mémoire alloué pour foo() dans la pile devient libre.
  • À la ligne 9, la méthode main() se termine et la mémoire de la pile créée pour la méthode main() est détruite. De plus, le programme se termine à cette ligne, donc Java Runtime libère toute la mémoire et met fin à l’exécution du programme.

Différence entre l’espace Heap Java et la mémoire de pile

Sur la base des explications ci-dessus, nous pouvons facilement conclure les différences suivantes entre la mémoire Heap et la mémoire de la pile.

  1. La mémoire Heap est utilisée par toutes les parties de l’application tandis que la mémoire de la pile est utilisée uniquement par un thread d’exécution.
  2. Chaque fois qu’un objet est créé, il est toujours stocké dans l’espace Heap et la mémoire de la pile contient la référence à celui-ci. La mémoire de la pile contient uniquement des variables primitives locales et des variables de référence vers des objets dans l’espace Heap.
  3. Les objets stockés dans le tas sont accessibles globalement tandis que la mémoire de la pile ne peut pas être accédée par d’autres threads.
  4. La gestion de la mémoire dans la pile se fait de manière LIFO tandis qu’elle est plus complexe dans la mémoire Heap car elle est utilisée globalement. La mémoire Heap est divisée en Young-Generation, Old-Generation, etc., plus de détails à Java Garbage Collection.
  5. La mémoire de la pile est de courte durée tandis que la mémoire Heap vit du début à la fin de l’exécution de l’application.
  6. Nous pouvons utiliser l’option JVM -Xms et -Xmx pour définir la taille de démarrage et la taille maximale de la mémoire Heap. Nous pouvons utiliser -Xss pour définir la taille de la mémoire de la pile.
  7. Lorsque la mémoire de la pile est pleine, l’exécution Java lance java.lang.StackOverFlowError tandis que si la mémoire Heap est pleine, elle lance une erreur java.lang.OutOfMemoryError: Java Heap Space.
  8. La taille de la mémoire de la pile est très faible par rapport à celle de la mémoire Heap. En raison de la simplicité de l’allocation de mémoire (LIFO), la mémoire de la pile est très rapide par rapport à la mémoire Heap.

C’est tout pour Java Heap Space vs Stack Memory en termes d’application Java, j’espère que cela dissipera vos doutes concernant l’allocation de mémoire lors de l’exécution de n’importe quel programme Java.

Référence: https://fr.wikipedia.org/wiki/Modèle_mémoire_Java.

Source:
https://www.digitalocean.com/community/tutorials/java-heap-space-vs-stack-memory