Accueil

Thèmes

Garbage Collection en Java

Qu'est-ce que Garbage Collection en Java ?
Découvrez la solution Garbage Collection en Java d'IBM S’inscrire pour recevoir les dernières informations sur l’IA
Illustration par un collage de pictogrammes représentant une roue dentée, un bras robotisé, un téléphone mobile
Qu'est-ce que Garbage Collection en Java ?

La solution Garbage Collection (ou récupération de mémoire) est une fonctionnalité principale du langage de programmation Java qui gère automatiquement l'allocation et la libération de mémoire pour les objets créés dans un espace eden.

Garbage Collection en Java permet aux développeurs de se concentrer sur l'écriture du code sans se soucier de la gestion de la mémoire, faisant de Java un choix populaire pour la création d'applications complexes et à grande échelle. Cependant, comprendre le fonctionnement de Garbage Collection est essentiel pour les développeurs Java afin d'optimiser les performances de leur code et d'éviter les erreurs courantes liées à la mémoire. 

Dans ce guide, les fondamentaux de Garbage Collection en Java sont à découvrir, notamment ses avantages, les différents types de collecteurs, et les bonnes pratiques à suivre lors du codage. Alors, entrons dans le vif du sujet et découvrons comment fonctionne Garbage Collection !

Total Economic Impact™ d’IBM Robotic Process Automation

Voir l’analyse des coûts et des avantages d’IBM Robotic Process Automation (RPA).

Contenu connexe Lire le guide sur l’observabilité
Qu’est-ce que OutofMemoryErrors ?

OutofMemoryError est une erreur qui survient lorsqu'un programme ou une application dépasse la mémoire disponible. Cette erreur se produit lorsque la Java Virtual Machine (JVM) ou une autre plateforme manque de mémoire lors de l'exécution d'une application.

Une erreur OutofMemoryError se produit généralement lorsque un programme ou une application tente de créer de nouveaux objets, mais que la JVM manque de mémoire pour les stocker. Cette erreur peut également se produire lorsqu’une application utilise trop de mémoire et ne la libère pas correctement.

Si une erreur OutofMemoryError survient, l'application se bloque souvent. Cette erreur est fréquente dans les programmes qui traitent de grandes quantités de métadonnées, comme les applications de traitement d'images ou de vidéos, ou les programmes qui gèrent de grandes bases de données.

Pour résoudre cette erreur, vous devrez peut-être augmenter la quantité de mémoire disponible pour l'application ou optimiser l'utilisation de la mémoire par l'application. Pour résoudre ce problème, vous pouvez modifier les paramètres de la JVM ou utiliser un outil de profilage de mémoire pour détecter les fuites de mémoire ou l'utilisation inefficace de la mémoire.

Comment fonctionne la récupération de mémoire en Java ?

En Java, le tas est la zone de mémoire utilisée pour stocker tous les objets, ce qui permet une allocation dynamique de la mémoire. Si un objet n'est plus accessible depuis le programme, il peut être récupéré par la récupération de mémoire.

Le récupérateur de mémoire en Java effectue des scans réguliers de la mémoire heap pour identifier les objets inutilisés. Le processus comprend plusieurs étapes, notamment le marquage, le balayage et le compactage.

  • Marquage - Première étape de la récupération, le marquage consiste à marquer tous les objets qui sont encore référencés par le programme. Cela s'effectue en partant d'un ensemble d'objets racines, tels que les variables globales, les variables locales et les paramètres de méthode, puis en traçant tous les objets accessibles à partir de ces racines. Les objets qui ne sont pas accessibles à partir des racines sont considérés comme éligibles à la récupération.

  • Balayage - Deuxième étape après le marquage, le balayage consiste à parcourir la mémoire du tas Java pour identifier et récupérer la mémoire utilisée par les objets qui ne sont plus référencés. La phase de balayage libère la mémoire utilisée par les objets non référencés et la réinjecte dans le pool de mémoire libre.

  • Compactage - Après le balayage, certains algorithmes de ramasse-miettes effectuent une phase de compactage, où la mémoire utilisée par les objets restants est réorganisée pour réduire la fragmentation. Ce processus consiste à rapprocher les objets et à créer des blocs de mémoire libres plus importants et continus.

La JVM (Java Virtual Machine) gère automatiquement la récupération de mémoire, ce qui dispense les programmeurs de la gestion manuelle de la mémoire. La récupération de mémoire est un processus parallèle qui s'exécute en arrière-plan, n'interférant pas avec l'exécution principale du programme.

Types de récupérateurs de mémoire en Java

Il existe deux principaux types d’algorithmes de Garbage Collection en Java : la récupération complète de la mémoire et la récupération incrémentielle de la mémoire.

Récupération de la mémoire complète

La récupération de mémoire complète est un processus systématique qui parcourt l'intégralité de la mémoire utilisée par un programme afin d'identifier et de supprimer les objets qui ne sont plus référencés. Ces objets sont marqués comme inutiles et peuvent être éliminés de la mémoire.

La récupération de mémoire complète est une fonctionnalité typique des systèmes d'exécution de langages de programmation avec gestion automatique de la mémoire, comme Java ou Python. Pendant le processus, le récupérateur interrompt l'exécution du programme pour rechercher les objets indésirables, ce qui peut entraîner un ralentissement temporaire des performances du programme.

La récupération de mémoire complète est activée lorsque la mémoire utilisée par un programme atteint un certain seuil ou lorsque le programme demande un nouveau bloc de mémoire et que la mémoire disponible est insuffisante. La récupération de mémoire complète permet de récupérer la mémoire inutilisée par le programme, ce qui la rend disponible pour d'autres parties du programme ou d'autres programmes en cours d'exécution sur la même machine..

Récupération incrémentielle de la mémoire

La récupération incrémentielle de la mémoire est une technique de gestion de la mémoire utilisée par les langages de programmation et les environnements d'exécution pour récupérer automatiquement la mémoire dont un programme n'a plus besoin. Cela fonctionne en identifiant les objets en mémoire qui ne sont plus utilisés et en libérant la mémoire qu'ils occupent pour la réutilisation par d'autres parties du programme.

Dans le cadre de la récupération incrémentielle, le récupérateur scanne périodiquement la mémoire du programme pour identifier les objets inaccessibles dans la mémoire heap de la jeune génération. Au lieu d'interrompre l'exécution du programme pendant ce processus de balayage, le récupérateur divise le balayage en petits morceaux gérables appelés « incréments ». À chaque incrément, le récupérateur scanne une partie de la mémoire du programme, identifiant les objets inutiles et les marquant comme disponibles pour la réutilisation.

En utilisant des incréments, le récupérateur peut récupérer de la mémoire par petites portions, sans interrompre l'exécution du programme pendant une longue période. Cela contribue à garantir que le programme reste réactif et ne subit pas de pauses ou de retards importants en raison du processus de récupération.

Cependant, la récupération incrémentielle peut être moins efficace que d'autres types de techniques de récupération de mémoire, comme le marquage-balayage ou la récupération générationnelle, car elle nécessite des scans plus fréquents de la mémoire du programme. De plus, l'utilisation d'incréments peut introduire une certaine surcharge dans l'exécution du programme, car le récupérateur de mémoire doit maintenir des informations d'état entre chaque incrément.

Avantages de la récupération de mémoire en Java

Globalement, la récupération de mémoire en Java présente de nombreux avantages qui en font un outil précieux pour les développeurs. Voici quelques avantages de l'utilisation de récupération de mémoire en Java :

  1. Pas de gestion manuelle de la mémoire
  2. Empêche les fuites de mémoire
  3. Allocation dynamique de la mémoire
  4. Performance améliorée
  5. Optimisation de la mémoire
  • Pas de gestion manuelle de la mémoire : Grâce à la récupération de mémoire, les développeurs n'ont pas besoin de gérer manuellement l'allocation et la désallocation de la mémoire. Cela permet aux développeurs de se concentrer davantage sur l'écriture de code et de réduire les erreurs liées à la gestion de la mémoire, ce qui améliore leur productivité.

  • Évite les fuites de mémoire : Le récupérateur de mémoire aide à éviter les fuites de mémoire, qui peuvent survenir lorsque un programme ne libère pas la mémoire inutilisée. Cela peut entraîner une consommation de mémoire excessive par le programme, ce qui peut ralentir ses performances et finalement provoquer une panne.

  • Allocation dynamique de la mémoire :Le récupérateur de mémoire en Java permet une allocation dynamique de la mémoire, ce qui signifie que la mémoire est allouée selon les besoins au moment de l'exécution. Cela contribue à prévenir les erreurs d'allocation de mémoire et peut améliorer l'efficacité du programme.

  • Amélioration des performances : La récupération de mémoire permet d'améliorer les performances d'un programme en réduisant le temps consacré à la gestion de la mémoire. Cette amélioration peut se traduire par des temps d'exécution plus rapides et une meilleure réactivité du programme.

  • Optimisation de la mémoire : La récupération de mémoire peut optimiser l'utilisation de la mémoire en réallouant la mémoire inutilisée à d'autres parties du programme. Cela peut optimiser l'utilisation de la mémoire, ce qui améliore l'efficacité globale du programme.

La récupération de mémoire en Java est un outil précieux pour les développeurs, car elle automatise la gestion de la mémoire, prévient les fuites de mémoire, permet une allocation dynamique de la mémoire, améliore les performances et optimise l'utilisation de la mémoire. Ces avantages contribuent à l'écriture de programmes de meilleure qualité et plus efficaces.

Quels événements déclenchent la récupération de mémoire en Java ?

En Java, la récupération de mémoire est déclenchée automatiquement par la JVM (Java Virtual Machine) lorsqu'elle détermine que le tas est en train de se remplir ou lorsqu'un certain temps s'est écoulé.

Plusieurs événements peuvent déclencher la récupération de mémoire en Java :

  • Allocation d'espace dans le tas : Lorsque la JVM doit allouer de la mémoire pour un nouvel objet et qu'il n'y a pas assez d'espace dans le tas, elle déclenche la récupération de mémoire pour récupérer la mémoire inutilisée ou la stocker dans l'espace survivant.

  • Appel de la méthode System.gc() : Il est possible de forcer la récupération de mémoire en appelant la méthode System.gc() , même s'il n'y a aucune garantie qu'elle s'exécute.

  • Seuil de la génération ancienne : La récupération de mémoire peut également être déclenchée lorsque la taille du tas de la génération ancienne (qui stocke les objets à longue durée de vie) atteint un certain seuil.

  • Seuil PermGen/Metaspace: La récupération de mémoire peut être déclenchée par le dépassement du seuil de taille des zones de mémoire PermGen (avant Java 8) ou Metaspace (Java 8 et versions ultérieures).

  • Basé sur le temps : Parfois, la récupération de mémoire peut être déclenchée en fonction d'un intervalle de temps. Par exemple, la JVM peut déclencher la récupération de mémoire toutes les heures ou tous les jours, indépendamment de l'utilisation de la mémoire.

Il convient de noter que le comportement exact de la récupération de mémoire en Java peut varier en fonction de l'implémentation et de la configuration de la JVM.

Comment demander à JVM d'exécuter Garbage Collector

Afin de déclencher la récupération de mémoire par la JVM (Java Virtual Machine), suivez ces étapes :

  1. Utilisez la méthode System.gc() : Pour déclencher la récupération de mémoire, appelez la méthode System.gc(). Il n'y a aucune garantie que le récupérateur s'exécutera immédiatement après l'appel de cette méthode.

  2. Utilisez la méthode Runtime.getRuntime().gc() : Cette méthode est similaire à la méthode System.gc() , mais elle est moins susceptible d’être remplacée par l’implémentation de la JVM.
  3. Utilisez l’indicateur JVM -XX:+DisableExplicitGC : Cet indicateur désactive les requêtes explicites de récupération de mémoire. Cela signifie que même si vous appelez System.gc() ou Runtime.getRuntime().gc(), le ramasse-miettes ne sera pas nécessairement déclenché.

Il convient de noter qu'il est généralement déconseillé de déclencher explicitement le récupérateur de mémoire, car la JVM est conçue pour gérer automatiquement l'allocation et la récupération de mémoire. Déclencher explicitement le récupérateur de mémoire peut parfois nuire aux performances. 

Quand un objet est-il éligible à la récupération de mémoire ?

Un objet dans un langage de programmation est éligible à la récupération de mémoire lorsqu'il n'est plus référencé par aucune partie du programme. La récupération automatique de mémoire est un processus effectué par l'environnement d'exécution du langage de programmation pour récupérer la mémoire.

Dans la plupart des langages de programmation modernes, la récupération de mémoire est effectuée automatiquement par l'environnement d'exécution. Les algorithmes spécifiques utilisés pour la récupération de mémoire peuvent varier en fonction du langage de programmation et de son implémentation, mais le principe général reste le même : l'environnement d'exécution scanne périodiquement le tas (la partie de la mémoire utilisée pour l'allocation dynamique des objets) pour identifier les objets qui ne sont plus accessibles à partir d'un objet vivant dans le programme. Lorsque un objet est identifié comme n'étant plus accessible, il est marqué comme orphelin, et sa mémoire peut être récupérée.

Le moment exact où un objet devient éligible à la récupération de mémoire dépend de l'algorithme de ramasse-miettes spécifique utilisé par l'environnement d'exécution. Certains algorithmes de récupération de mémoire sont plus agressifs que d'autres et peuvent récupérer la mémoire plus rapidement, tandis que d'autres peuvent retarder la récupération de mémoire pour optimiser les performances. Cependant, en général, le programmeur n'a pas besoin de se soucier de la gestion manuelle de la mémoire, car l'environnement d'exécution s'en charge automatiquement.

Quels sont les récupérateurs de mémoire disponibles pour Java ?

Il existe plusieurs récupérateurs de mémoire Java, notamment :

  1. Serial Garbage Collector
  2. Parallel Garbage Collector
  3. Concurrent Mark Sweep (CMS) Collector
  4. G1 Garbage Collector
  • Serial Garbage Collector : Le Serial Collector est le récupérateur par défaut de Java. Il est généralement utilisé pour les applications de petite à moyenne taille qui n'exigent pas un débit élevé. Ce type de récupérateur de mémoire permet d'éviter les interruptions fréquentes du processus Java, connues sous le nom de « Stop the World ».

  • Parallel Garbage Collector : le Parallel Collector est idéal pour les applications qui ont besoin de beaucoup de puissance de calcul. Il est particulièrement utile pour les applications qui utilisent beaucoup de mémoire car il profite de plusieurs processeurs. Il est à noter que ce type de récupérateur de mémoire peut occasionnellement interrompre temporairement l'exécution des fils de l'application pendant le processus de récupération de mémoire.

  • Concurrent Mark Sweep (CMS) Collector : Le CMS Collector est optimisé pour les applications exigeant des pauses minimales. Il est particulièrement efficace dans les applications avec un grand nombre d'objets en cours d'utilisation.

  • G1 Garbage Collector : Le G1 Collector est optimisé pour les applications utilisant de grandes mémoires et peut gérer efficacement des objets de durée de vie variable. Il utilise plusieurs fils pour analyser et compacter simultanément la mémoire.

Chaque récupérateur de mémoire présente ses propres avantages et inconvénients, et le choix du récupérateur à utiliser dépend des besoins spécifiques de l'application. Il est également possible de configurer et de régler les paramètres du récupérateur de mémoire pour optimiser les performances d'une application spécifique.

Quelle est la différence entre la récupération de mémoire et la fuite de mémoire ?

La récupération de mémoire et les fuites de mémoire sont toutes deux liées à la gestion de la mémoire, mais elles ont des significations et des conséquences différentes.

Comme indiqué précédemment, la récupération de mémoire est généralement effectuée par le langage de programmation ou l'environnement d'exécution, et elle contribue à garantir que les programmes ne consomment pas plus de mémoire que nécessaire. La récupération de mémoire identifie la mémoire qui peut être réutilisée par d'autres parties du programme ou par d'autres programmes exécutés sur l'ordinateur.

En revanche, une fuite de mémoire se produit lorsqu'un programme ne libère pas la mémoire qu'il a allouée, même lorsque cette mémoire n'est plus nécessaire. Par conséquent, le programme continue à consommer de la mémoire au fil du temps, ce qui entraîne finalement l'épuisement de la mémoire disponible, pouvant provoquer le blocage du programme ou de l'ensemble du système d'exploitation. Les fuites de mémoire sont généralement causées par des erreurs dans le programme et peuvent être difficiles à identifier et à corriger.

En résumé, la récupération de mémoire est un processus qui libère automatiquement la mémoire qui n'est plus utilisée. Les fuites de mémoire se produisent lorsque la mémoire est allouée mais non libérée par un programme, entraînant une accumulation progressive de l'utilisation de la mémoire.

Instana vous permet de suivre les performances de votre application Java

En conclusion, la récupération de mémoire est un aspect essentiel de la programmation Java qui garantit une gestion efficace de la mémoire en récupérant la mémoire inutilisée. Instana Observability offre aux développeurs des outils puissants pour surveiller et optimiser en temps réel le processus de récupération de mémoire. 

En utilisant Instana, les développeurs peuvent rapidement identifier les fuites de mémoire, optimiser les paramètres de récupération de mémoire et résoudre les problèmes de performance liés à la récupération de mémoire.

Grâce aux capacités de surveillance complètes d'Instana, les développeurs peuvent acquérir des connaissances approfondies sur l'utilisation de la mémoire et le comportement de la récupération de mémoire de leurs applications Java, leur permettant de fournir un logiciel performant et fiable. 

En appliquant les bonnes pratiques présentées dans ce guide, les développeurs peuvent utiliser Instana pour optimiser le processus de récupération de mémoire et améliorer les performances générales de leurs applications Java. Grâce à Instana Observability, les développeurs peuvent anticiper tout problème potentiel, garantissant ainsi que leurs applications fonctionnent toujours au meilleur de leurs capacités.

Produits associés
IBM Instana Observability

Améliorez les fonctionnalités et l’observabilité dans l’APM de votre entreprise : améliorez la gestion de la performance des applications et accélérez les pipelines CI/CD, et ce quel que soit l’emplacement des applications.

Découvrir IBM Instana Observability

Ressources Qu’est-ce que l’observabilité ?

Observability offre une visibilité approfondie des applications distribuées modernes pour une identification et une résolution plus rapides et automatisées des problèmes.

Qu’est-ce que Java ?

Découvrez pourquoi Java reste une plateforme de développement très populaire et comment elle permet de réaliser des projets plus rapidement et de prendre en charge toute une panoplie de technologies émergentes.

Qu’est-ce que le développement de logiciels ?

Apprenez les bases du développement de logiciels et découvrez comment il permet aux entreprises d’innover et de rester compétitives.

Qu’est-ce que l’environnement d’exécution Java (JRE) ?

Découvrez les fonctionnalités de l'environnement d'exécution Java (JRE) et son fonctionnement avec les autres composants de la plateforme Java pour exécuter des applications Java.

Qu'est-ce que la gestion des performances des applications (APM) ?

Adoptez la gestion de la performance des applications pour anticiper et prévenir les problèmes de performance.

Qu’est-ce que l’ingénierie de la fiabilité des sites (SRE) ?

Automatisez les tâches opérationnelles informatiques, accélérez la livraison de logiciels et minimisez les risques informatiques grâce à l’ingénierie de la fiabilité des sites.

Passez à l’étape suivante

IBM Instana fournit une observabilité en temps réel que tout le monde peut utiliser. La solution accélère la création de valeur tout en vérifiant que votre stratégie d’observabilité peut s’adapter à la complexité dynamique des environnements actuels et futurs. Du mobile au mainframe, Instana prend en charge plus de 250 technologies, et poursuit son expansion. 

Découvrir IBM Instana Réserver une démo en direct