Gestion de la mémoire dans Java
Qu'est-ce que la mémoire de pile ?
La pile en Java est une section de mémoire qui contient des méthodes, des variables locales et des variables de référence. La mémoire de pile est toujours référencée dans l'ordre Last-In-First-Out. Les variables locales sont créées dans la pile.
Qu’est-ce que la mémoire tas ?
Le tas est une section de mémoire qui contient des objets et peut également contenir des variables de référence. Les variables d'instance sont créées dans le tas.
Allocation de mémoire dans Java
Allocation de mémoire dans Java est le processus dans lequel les sections de mémoire virtuelle sont mises de côté dans un programme de stockage des variables et des instances de structures et de classes. Cependant, la mémoire n'est pas allouée à un objet lors de la déclaration mais seule une référence est créée. Pour l'allocation de mémoire de l'objet, la méthode new() est utilisée, de sorte que l'objet se voit toujours allouer de la mémoire sur le tas.
La Java L'allocation de mémoire est divisée en sections suivantes :
- Heap
- Stack
- Code
- Statique
Cette division de la mémoire est nécessaire à sa gestion efficace.
- La code la section contient votre bytecode.
- La Stack la section de mémoire contient méthodes, variables locales et variables de référence.
- La Heap la section contient Objets (peut également contenir des variables de référence).
- La Statique la section contient Données/méthodes statiques.
Différence entre la variable locale et la variable d'instance
Variable d'instance est déclaré à l'intérieur d'une classe mais pas à l'intérieur d'une méthode
class Student{ int num; // num is instance variable public void showData{}
Variable locale sont déclarés à l'intérieur a méthode comprenant méthode arguments.
public void sum(int a){ int x = int a + 3; // a , x are local variables; }
Différence entre pile et tas
Cliquez sur ici. si la vidéo n'est pas accessible
Prenons un exemple pour mieux comprendre cela. Considérons que votre méthode principale appelle la méthode m1
public void m1{ int x=20 }
Dans la stack java, un frame sera créé à partir de la méthode m1.
La variable X dans m1 sera également créée dans le cadre de m1 dans la pile. (Voir l'image ci-dessous).
La méthode m1 appelle la méthode m2. Dans la pile Java, un nouveau frame est créé pour m2 au-dessus du frame m1.
Les variables b et c seront également créées dans un frame m2 dans une pile.
public void m2(int b){ boolean c; }
La même méthode m2 appelle la méthode m3. De nouveau, un cadre m3 est créé en haut de la pile (voir image ci-dessous).
Supposons maintenant que notre méthode m3 crée un objet pour la classe « Compte », qui a deux variable d'instance int p et int q.
Account { Int p; Int q; }
Voici le code de la méthode m3
public void m3(){ Account ref = new Account(); // more code }
L'instruction new Account() créera un objet de compte en tas.
La variable de référence « ref » sera créée dans une pile java.
L'opérateur d'affectation « = » créera une variable de référence pour pointer vers l'objet dans le tas.
Une fois que la méthode a terminé son exécution, le flux de contrôle revient à la méthode appelante. Dans ce cas, il s'agit de la méthode m2.
La pile de la méthode m3 sera vidée.
Étant donné que la variable de référence ne pointera plus vers l’objet dans le tas, elle serait éligible au garbage collection.
Une fois que la méthode m2 a terminé son exécution, elle sera retirée de la pile et toutes ses variables seront vidées et ne pourront plus être utilisées.
De même pour la méthode m1.
Finalement, le flux de contrôle reviendra au point de départ du programme, qui est généralement la méthode « main ».
Et si Object avait une référence comme variable d’instance ?
public static void main(String args[]) { A parent = new A(); //more code } class A{ B child = new B(); int e; //more code } class B{ int c; int d; //more code }
Dans ce cas, la variable de référence « enfant » sera créée dans le tas, qui à son tour pointera vers son objet, quelque chose comme le diagramme ci-dessous.
Qu’est-ce que la collecte des déchets Java?
Collecte des déchets à Java est un processus par lequel les programmes effectuent automatiquement la gestion de la mémoire. Le Garbage Collector (GC) trouve les objets inutilisés et les supprime pour récupérer la mémoire. Dans Java, l'allocation dynamique de mémoire des objets est obtenue à l'aide de l'opérateur new qui utilise une partie de la mémoire et la mémoire reste allouée jusqu'à ce qu'il y ait des références pour l'utilisation de l'objet.
Lorsqu'il n'y a aucune référence à un objet, celui-ci est supposé n'être plus nécessaire et la mémoire occupée par l'objet peut être récupérée. Il n'y a pas de besoin explicite de détruire un objet car Java gère automatiquement la désallocation.
La technique qui permet d'y parvenir est connue sous le nom de Collecte des ordures. Les programmes qui ne libèrent pas de mémoire peuvent éventuellement planter lorsqu'il n'y a plus de mémoire à allouer dans le système. Ces programmes auraient fuites de mémoire. Collecte des déchets à Java se produit automatiquement pendant la durée de vie du programme, éliminant ainsi le besoin de désallouer de la mémoire et évitant ainsi les fuites de mémoire.
En langage C, il est de la responsabilité du programmeur de désallouer la mémoire allouée dynamiquement à l'aide de la fonction free(). C'est ici Java la gestion de la mémoire mène.
Remarque: Tous les objets sont créés dans la section Heap de la mémoire. Plus d'informations à ce sujet dans un prochain tutoriel.
Exemple : Pour apprendre le mécanisme du collecteur de déchets dans Java
Étape 1) Copiez le code suivant dans un éditeur.
class Student{ int a; int b; public void setData(int c,int d){ a=c; b=d; } public void showData(){ System.out.println("Value of a = "+a); System.out.println("Value of b = "+b); } public static void main(String args[]){ Student s1 = new Student(); Student s2 = new Student(); s1.setData(1,2); s2.setData(3,4); s1.showData(); s2.showData(); //Student s3; //s3=s2; //s3.showData(); //s2=null; //s3.showData(); //s3=null; //s3.showData(); } }
Étape 2) Enregistrez, compilez et exécutez le code. Comme le montre le diagramme, deux objets et deux variables de référence sont créés.
Étape 3) Décommentez la ligne #20,21,22. Enregistrez, compilez et exécutez le code.
Étape 4) Comme le montre le diagramme ci-dessous, deux variables de référence pointent vers le même objet.
Étape 5) Décommentez les lignes n°23 et 24. Compilez, enregistrez et exécutez le code
Étape 6) Comme le montre le diagramme ci-dessous, s2 devient nul, mais s3 pointe toujours vers l'objet et n'est pas éligible pour le garbage collection Java.
Étape 7) Décommentez les lignes n°25 et 26. Enregistrez, compilez et exécutez le code
Étape 8) À ce stade, il n'y a aucune référence pointant vers l'objet et devient éligible pour le garbage collection. Il sera supprimé de la mémoire et il n’existe aucun moyen de le récupérer.
Comment supprimer un objet dans Java?
1) Si vous souhaitez rendre votre objet éligible au Garbage Collection, attribuez sa variable de référence à null.
2) Les types primitifs ne sont pas des objets. Ils ne peuvent pas être attribués à null.
Résumé :
- Lorsqu'une méthode est appelée, un cadre est créé en haut de la pile.
- Une fois l'exécution d'une méthode terminée, le flux de contrôle revient à la méthode appelante et son cadre de pile correspondant est vidé.
- Les variables locales sont créées dans la pile
- Les variables d'instance sont créées dans le tas et font partie de l'objet auquel elles appartiennent.
- Les variables de référence sont créées dans la pile.