logo

Gestion de la mémoire en Java

En Java, la gestion de la mémoire est le processus d'allocation et de désallocation d'objets, appelé gestion de la mémoire. Java gère automatiquement la mémoire. Java utilise un système de gestion automatique de la mémoire appelé Éboueur . Ainsi, nous ne sommes pas obligés d’implémenter une logique de gestion de mémoire dans notre application. La gestion de la mémoire Java se divise en deux parties principales :

    Structure de la mémoire JVM Fonctionnement du éboueur

Structure de la mémoire JVM

JVM crée diverses zones de données d'exécution dans un tas. Ces zones sont utilisées lors de l'exécution du programme. Les zones de mémoire sont détruites à la sortie de la JVM, tandis que les zones de données sont détruites à la sortie du thread.

Gestion de la mémoire en Java

Zone de méthode

La zone de méthode est une partie de la mémoire tas qui est partagée entre tous les threads. Il se crée au démarrage de la JVM. Il est utilisé pour stocker la structure de classe, le nom de la superclasse, le nom de l'interface et les constructeurs. La JVM stocke les types d'informations suivants dans la zone méthode :

chaîne en entier en java
  • Un nom complet d'un type (ex : String)
  • Les modificateurs du type
  • Nom de superclasse direct du type
  • Une liste structurée des noms complets des super interfaces.

Zone de tas

Heap stocke les objets réels. Il se crée au démarrage de la JVM. L'utilisateur peut contrôler le tas si nécessaire. Il peut être de taille fixe ou dynamique. Lorsque vous utilisez un nouveau mot-clé, la JVM crée une instance pour l'objet dans un tas. Alors que la référence de cet objet est stockée dans la pile. Il n'existe qu'un seul tas pour chaque processus JVM en cours d'exécution. Lorsque le tas est plein, les déchets sont collectés. Par exemple:

 StringBuilder sb= new StringBuilder(); 

L'instruction ci-dessus crée un objet de la classe StringBuilder. L'objet est alloué au tas et la référence sb est allouée à la pile. Le tas est divisé en parties suivantes :

  • Jeune génération
  • Espace survivant
  • Ancienne génération
  • Génération permanente
  • Cache de codes

Type de référence

Il existe quatre types de références : Fort , Faible , Doux , et Référence fantôme . La différence entre les types de références est que les objets sur le tas auxquels ils font référence sont éligibles au garbage collection selon différents critères.

Référence forte : C'est très simple puisque nous l'utilisons dans notre programmation quotidienne. Tout objet auquel est attachée une référence Strong n’est pas éligible pour le garbage collection. Nous pouvons créer une référence forte en utilisant l'instruction suivante :

 StringBuilder sb= new StringBuilder(); 

Faible référence : Il ne survit pas après le prochain processus de collecte des ordures. Si nous ne savons pas quand les données seront à nouveau demandées. Dans cette condition, nous pouvons y créer une faible référence. Dans le cas où, si le garbage collector traite, il détruit l'objet. Lorsque nous essayons à nouveau de récupérer cet objet, nous obtenons une valeur nulle. Il est défini dans java.lang.ref.WeakReference classe. Nous pouvons créer une référence faible en utilisant l'instruction suivante :

 WeakReference reference = new WeakReference(new StringBuilder()); 

Référence souple : Il est collecté lorsque l’application manque de mémoire. Le garbage collector ne collecte pas les objets facilement accessibles. Tous les objets référencés logiciellement sont collectés avant de générer une OutOfMemoryError. Nous pouvons créer une référence logicielle en utilisant l'instruction suivante :

 SoftReference reference = new SoftReference(new StringBuilder()); 

Référence fantôme : Il est disponible dans java.lang.ref emballer. Il est défini dans java.lang.ref.PhantomReference classe. L'objet qui n'a qu'une référence fantôme pointant vers lui peut être collecté chaque fois que le garbage collector souhaite le collecter. Nous pouvons créer une référence fantôme en utilisant l'instruction suivante :

 PhantomReference reference = new PhantomReference(new StringBuilder()); 

Zone de pile

La zone de pile est générée lorsqu'un thread est créé. Il peut être de taille fixe ou dynamique. La mémoire de la pile est allouée par thread. Il est utilisé pour stocker des données et des résultats partiels. Il contient des références à des objets de tas. Il contient également la valeur elle-même plutôt qu'une référence à un objet du tas. Les variables stockées dans la pile ont une certaine visibilité, appelée portée.

Cadre de pile : Le cadre de pile est une structure de données qui contient les données du thread. Les données du thread représentent l'état du thread dans la méthode actuelle.

  • Il est utilisé pour stocker des résultats et des données partiels. Il effectue également des liaisons dynamiques, des valeurs renvoyées par des méthodes et des exceptions de répartition.
  • Lorsqu'une méthode est invoquée, un nouveau frame est créé. Il détruit le frame une fois l'invocation de la méthode terminée.
  • Chaque trame contient son propre tableau de variables locales (LVA), sa propre pile d'opérandes (OS) et ses propres données de trame (FD).
  • Les tailles de LVA, OS et FD sont déterminées au moment de la compilation.
  • Une seule trame (la trame pour l’exécution de la méthode) est active à tout moment dans un thread de contrôle donné. Cette trame est appelée la trame actuelle et sa méthode est connue sous le nom de méthode actuelle. La classe de la méthode est appelée la classe actuelle.
  • Le frame arrête la méthode en cours, si sa méthode appelle une autre méthode ou si la méthode se termine.
  • Le cadre créé par un thread est local à ce thread et ne peut être référencé par aucun autre thread.

Pile de méthodes natives

Elle est également connue sous le nom de pile C. Il s'agit d'une pile de code natif écrit dans un langage autre que Java. Java Native Interface (JNI) appelle la pile native. Les performances de la pile native dépendent du système d'exploitation.

centrer l'image en CSS

Registres PC

Chaque thread est associé à un registre de compteur de programme (PC). Le registre PC stocke l'adresse de retour ou un pointeur natif. Il contient également l'adresse des instructions JVM en cours d'exécution.

Fonctionnement d'un éboueur

Présentation du collecteur de déchets

Lorsqu'un programme s'exécute en Java, il utilise la mémoire de différentes manières. Le tas est une partie de la mémoire où vivent les objets. C'est la seule partie de la mémoire impliquée dans le processus de récupération de place. Il est également connu sous le nom de tas de déchets collectables. Tout le garbage collection garantit que le tas dispose d'autant d'espace libre que possible. La fonction du garbage collector est de rechercher et de supprimer les objets inaccessibles.

Attribution d'objet

Lorsqu'un objet est alloué, la JVM JRockit vérifie la taille de l'objet. Il fait la distinction entre les petits et les grands objets. La petite et la grande taille dépendent de la version de la JVM, de la taille du tas, de la stratégie de garbage collection et de la plate-forme utilisée. La taille d'un objet est généralement comprise entre 2 et 128 Ko.

Les petits objets sont stockés dans la Thread Local Area (TLA), qui est un morceau libre du tas. TLA ne se synchronise pas avec les autres threads. Lorsque TLA est plein, il demande un nouveau TLA.

D'un autre côté, les objets volumineux qui ne rentrent pas dans le TLA sont directement alloués au tas. Si un thread utilise le jeune espace, il est directement stocké dans l'ancien espace. Le gros objet nécessite plus de synchronisation entre les threads.

Qu'est-ce que Java Garbage Collector ?

JVM contrôle le garbage collector. JVM décide quand effectuer le garbage collection. Nous pouvons également demander à la JVM d'exécuter le garbage collector. Mais il n'y a aucune garantie, quelles que soient les conditions, que la JVM sera conforme. La JVM exécute le garbage collector si elle détecte que la mémoire est faible. Lorsque le programme Java demande le garbage collector, la JVM accorde généralement la demande dans un bref délai. Il ne garantit pas que les demandes soient acceptées.

Le point à comprendre est que ' quand un objet devient éligible au garbage collection ? '

Chaque programme Java possède plusieurs threads. Chaque thread a sa pile d'exécution. Il existe un thread à exécuter dans le programme Java qui est une méthode main(). Nous pouvons désormais dire qu'un objet est éligible au garbage collection lorsqu'aucun thread actif ne peut y accéder. Le garbage collector considère cet objet comme éligible à la suppression. Si un programme a une variable de référence qui fait référence à un objet, cette variable de référence disponible pour le thread en direct, cet objet est appelé accessible .

Ici, une question se pose : «  Une application Java peut-elle manquer de mémoire ? '

La réponse est oui. Le système de récupération de place tente de récupérer les objets de la mémoire lorsqu'ils ne sont pas utilisés. Cependant, si vous gérez de nombreux objets actifs, le garbage collection ne garantit pas qu'il y ait suffisamment de mémoire. Seule la mémoire disponible sera gérée efficacement.

Types de collecte des déchets

Il existe cinq types de collecte des déchets :

inversion de chaîne en c
    CPG série :Il utilise l'approche Mark and Sweeps pour les jeunes et les vieilles générations, qui est GC mineure et majeure.CPG parallèle :Il est similaire au GC série, sauf qu'il génère N (le nombre de cœurs de processeur dans le système) threads pour le garbage collection de jeune génération.Ancien GC parallèle :Il est similaire au GC parallèle, sauf qu'il utilise plusieurs threads pour les deux générations.Collecteur de balayage de marques simultanées (CMS) :Elle fait le ramassage des déchets pour l'ancienne génération. Vous pouvez limiter le nombre de threads dans le collecteur CMS en utilisant XX:ParalleCMSThreads=option JVM . Il est également connu sous le nom de collecteur de pauses faibles simultanées.Collecteur de déchets G1 :Il a été introduit dans Java 7. Son objectif est de remplacer le collecteur CMS. Il s'agit d'un collecteur parallèle, simultané et CMS. Il n’y a pas d’espace pour les jeunes et les vieilles générations. Il divise le tas en plusieurs tas de taille égale. Il collecte d’abord les régions avec moins de données en direct.

Algorithme de marquage et de balayage

JRockit JVM utilise l'algorithme de marquage et de balayage pour effectuer le garbage collection. Il contient deux phases, la phase de marquage et la phase de balayage.

Phase de marquage : Les objets accessibles à partir des threads, des handles natifs et d’autres sources racine GC sont marqués comme actifs. Chaque arborescence d'objets a plusieurs objets racine. La racine GC est toujours accessible. Donc, tout objet qui a une racine de garbage collection à sa racine. Il identifie et marque tous les objets utilisés, et le reste peut être considéré comme un déchet.

Gestion de la mémoire en Java

Phase de balayage : Dans cette phase, le tas est parcouru pour trouver l'écart entre les objets vivants. Ces lacunes sont enregistrées dans la liste libre et sont disponibles pour l'attribution de nouveaux objets.

Il existe deux versions améliorées de Mark et Sweep :

    Marquage et balayage simultanés Marque parallèle et balayage

Marquage et balayage simultanés

Cela permet aux threads de continuer à s'exécuter pendant une grande partie du garbage collection. Il existe les types de marquage suivants :

    Marquage initial :Il identifie l'ensemble racine des objets vivants. Cela se fait pendant que les threads sont en pause.Marquage simultané :Dans ce marquage, les références de l'ensemble racine sont suivies. Il trouve et marque le reste des objets vivants dans un tas. Cela se fait pendant que le thread est en cours d'exécution.Marquage avant nettoyage :Il identifie les modifications apportées par le marquage concurrent. Autres objets vivants marqués et trouvés. Cela se fait pendant que les threads sont en cours d'exécution.Notation finale :Il identifie les modifications apportées par le marquage avant nettoyage. Autres objets vivants marqués et trouvés. Cela se fait pendant que les threads sont en pause.

Marque parallèle et balayage

Il utilise tout le processeur disponible dans le système pour effectuer le garbage collection aussi rapidement que possible. On l’appelle également le ramasse-miettes parallèle. Les threads ne s'exécutent pas lorsque le garbage collection parallèle s'exécute.

Avantages de Mark et Sweep

  • C'est un processus récurrent.
  • C'est une boucle infinie.
  • Aucune surcharge supplémentaire autorisée lors de l’exécution d’un algorithme.

Inconvénients de Mark et Sweep

  • Il arrête l'exécution normale du programme pendant l'exécution de l'algorithme de récupération de place.
  • Il s'exécute plusieurs fois sur un programme.