Qu'est-ce que le garbage collector en Java?

103

Je suis nouveau sur Java et confus au sujet du ramasse-miettes en Java. Que fait-il réellement et quand entre-t-il en action. Veuillez décrire certaines des propriétés du garbage collector en Java.

Subhransu Mishra
la source
2
possible duplicate of Garbage Collection
Ian Ringrose
10
Parfois, il est préférable de lire un chapitre dans un bon livre et de comprendre un sujet complexe à partir de la réponse à une question.
Ian Ringrose le
4
@Ian C'est une question similaire, mais pas un doublon. Et cette question pue les devoirs.
NullUserException

Réponses:

119

Le garbage collector est un programme qui s'exécute sur la machine virtuelle Java qui supprime les objets qui ne sont plus utilisés par une application Java. C'est une forme de gestion automatique de la mémoire .

Lorsqu'une application Java typique est en cours d'exécution, elle crée de nouveaux objets, tels que Strings et Files, mais après un certain temps, ces objets ne sont plus utilisés. Par exemple, regardez le code suivant:

for (File f : files) {
    String s = f.getName();
}

Dans le code ci-dessus, le String sest en cours de création à chaque itération de la forboucle. Cela signifie qu'à chaque itération, un peu de mémoire est allouée pour créer un Stringobjet.

En revenant au code, nous pouvons voir qu'une fois qu'une seule itération est exécutée, dans l'itération suivante, l' Stringobjet qui a été créé dans l'itération précédente n'est plus utilisé - cet objet est maintenant considéré comme "garbage".

Finalement, nous commencerons à avoir beaucoup de déchets et la mémoire sera utilisée pour les objets qui ne sont plus utilisés. Si cela continue, la machine virtuelle Java finira par manquer d'espace pour créer de nouveaux objets.

C'est là qu'intervient le garbage collector.

Le ramasse-miettes recherchera les objets qui ne sont plus utilisés et s'en débarrasse, libérant ainsi de la mémoire afin que d'autres nouveaux objets puissent utiliser cette partie de la mémoire.

En Java, la gestion de la mémoire est prise en charge par le garbage collector, mais dans d'autres langages tels que C, il faut effectuer la gestion de la mémoire de manière autonome en utilisant des fonctions telles que mallocetfree . La gestion de la mémoire est une de ces choses qui sont faciles à commettre des erreurs, qui peuvent conduire à ce que l'on appelle des fuites de mémoire - des endroits où la mémoire n'est pas récupérée quand ils ne sont plus utilisés.

Les schémas de gestion automatique de la mémoire comme le ramasse-miettes permettent au programmeur de ne pas trop se soucier des problèmes de gestion de la mémoire, afin qu'il puisse se concentrer davantage sur le développement des applications dont il a besoin.

coobird
la source
Serait-il vrai de dire qu'une application Java s'exécutant sur un ordinateur dispose alors de deux fonctionnalités de garbage collection. Un avec la machine virtuelle Java. Et puis un sur la machine réelle qui exécute Windows? (Ou tout autre système d'exploitation)
Lealo
Non, les applications Java ne s'exécutent généralement que si JRE est présent. Ainsi, seule la fonctionnalité de récupération de place de JVM est requise! @Lealo
Am_I_Helpful
18

Il libère la mémoire allouée aux objets qui ne sont plus utilisés par le programme - d'où le nom «garbage». Par exemple:

public static Object otherMethod(Object obj) {
    return new Object();
}

public static void main(String[] args) {
    Object myObj = new Object();
    myObj = otherMethod(myObj);
    // ... more code ...  
}

Je sais que c'est extrêmement artificiel, mais ici après que vous appelez otherMethod()l'original Objectcréé est rendu inaccessible - et c'est "garbage" qui obtient des ordures collectées.

En Java, le GC s'exécute automatiquement, mais vous pouvez également l'appeler explicitement avec System.gc()et essayer de forcer un important garbage collection. Comme le souligne Pascal Thivent, vous ne devriez vraiment pas avoir à faire cela et cela pourrait faire plus de mal que de bien (voir cette question ).

Pour plus d'informations, consultez l'entrée wikipedia sur le garbage collection et Tuning Garbage Collection (à partir d'Oracle)

NullUserException
la source
1
AFAIK System.gc()ne force pas le GC à s'exécuter.
Itay Karo du
1
+1 pour le bon exemple de code. Notez qu'il est parfaitement valide pour le GC de détruire myObjavant que l'appel à ait otherMethodlieu, car il myObjn'est plus accessible à ce stade.
Billy ONeal du
@Italie Je pense que c'est spécifique à la mise en œuvre.
NullUserException le
2
Je crois qu'il ne faut pas appeler System.gc(), tout l'intérêt d'avoir un CG est de ne pas avoir à faire cela.
Pascal Thivent
avec l'analyse d'échappement ( en.wikipedia.org/wiki/Escape_analysis ), il est possible que la JVM n'alloue même pas l'objet en premier lieu dans cet exemple. L'ensemble de la création d'objet peut (en théorie) être optimisé. La mise en œuvre dépend bien sûr.
mikera
15

Un objet devient éligible pour le garbage collection ou GC s'il n'est pas accessible à partir de threads en direct ou par des références statiques.

En d'autres termes, vous pouvez dire qu'un objet devient éligible pour le garbage collection si toutes ses références sont nulles. Les dépendances cycliques ne sont pas comptées comme référence, donc si l'objet A a une référence à l'objet B et que l'objet B a une référence à l'objet A et qu'ils n'ont aucune autre référence en direct, alors les objets A et B seront éligibles pour le garbage collection.


Générations de tas pour le garbage collection -

Les objets Java sont créés Heapet Heapsont divisés en trois parties ou générations pour le bien de la collecte des déchets en Java, ils sont appelés Young (New) generation, Tenured (Old) Generation et Perm Area du tas.

Java heap space New Generation est divisée en trois parties appelées espace Eden, espace Survivor 1 et Survivor 2. Lorsqu'un objet créé pour la première fois dans le tas, il est créé dans une nouvelle génération dans l'espace Eden et après un ramassage des ordures mineur ultérieur, si un objet survit, il est déplacé vers le survivant 1, puis le survivant 2 avant que le ramassage des ordures majeur ne déplace cet objet vers la génération ancienne ou permanente .

L'espace Perm de Java Heap est l'endroit où la JVM stocke les métadonnées sur les classes et les méthodes, le pool de chaînes et les détails de niveau de classe.

Générations de tas pour la récupération de place

Reportez-vous ici pour en savoir plus: Garbage Collection


Vous ne pouvez pas forcer JVM à exécuter Garbage Collection bien que vous puissiez faire une demande à l'aide de la méthode System.gc()ou Runtime.gc().

Dans java.lang.System

public static void gc() {
    Runtime.getRuntime().gc();  
}

Dans java.lang.Runtime

public native void gc();  // note native  method

Algorithme Mark and Sweep -

C'est l'un des algorithmes les plus populaires utilisés par Garbage collection. Tout algorithme de garbage collection doit effectuer 2 opérations de base. Premièrement, il doit être capable de détecter tous les objets inaccessibles et, deuxièmement, il doit récupérer l'espace de tas utilisé par les objets poubelle et rendre l'espace à nouveau disponible pour le programme.

Les opérations ci-dessus sont effectuées par l'algorithme Mark and Sweep en deux phases:

  1. Marquer la phase
  2. Phase de balayage

lisez ici pour plus de détails - Algorithme Mark and Sweep

roottraveller
la source
6

garbage collector implique que les objets dont le programme n'a plus besoin sont des «déchets» et peuvent être jetés.

Nik
la source
6

Garbage Collector fait partie de JRE qui garantit que les objets qui ne sont pas référencés seront libérés de la mémoire.
Il s'exécute généralement lorsque votre application manque de mémoire. AFAIK il détient un graphe qui représente les liens entre les objets et les objets isolés peuvent être libérés.
Pour économiser les performances, les objets actuels sont regroupés en générations, chaque fois que GC scanne un objet et constate qu'il est toujours référencé, son nombre de générations est incrémenté de 1 (jusqu'à une valeur maximale maximale, 3 ou 4 je pense), et la nouvelle génération est analysée en premier (plus l'objet en mémoire est court, plus il n'est probablement plus nécessaire) donc tous les objets ne sont pas analysés à chaque exécution du GC.
lisez ceci pour plus d'informations.

Itay Karo
la source
@quantumSoup êtes-vous positif à ce sujet? Je crois qu'une sorte de ramassage des ordures (plus cher) ne se produit que lorsque le tas se remplit.
Pablo Fernandez du
2
@quantumSoup - cela dépend de l'implémentation GC du JRE. Dans de nombreux cas, le GC ne fonctionne pas en permanence. Au lieu de cela, il s'exécute lorsque votre application ne peut pas allouer un objet car le tas est plein. Les JVM HotSpot récents incluent un GC parallèle, mais il n'est pas activé par défaut.
Stephen C du
Cette réponse se concentre trop sur le mécanisme. La question était "Qu'est-ce que le ramasse-miettes", pas "Comment fonctionne le ramasse-miettes"
Billy ONeal
@quantum: a neutralisé votre -1, car: Apprendre, c'est à quoi sert cette page, non? Pour apprendre, vous devez faire des erreurs. Punir les erreurs empêche les gens d'apprendre. J'espère que vous pouvez être d'accord sur ce point. Et peut-être avez-vous fait une erreur ici.
erikbwork
1
@erikb: Selon cette logique, il n'y aurait jamais de votes négatifs. Et des votes négatifs sont nécessaires pour éliminer les réponses relativement pauvres. L'OP est évidemment un débutant, et le fonctionnement interne spécifique du GC n'est tout simplement pas important pour la question posée. Puisque cette réponse ne répond pas à la question posée (elle en répond à une autre), les votes négatifs sont parfaitement justifiés.
Billy ONeal
3

Le ramasse-miettes permet à votre ordinateur de simuler un ordinateur avec une mémoire infinie. Le reste n'est que mécanisme.

Il le fait en détectant quand des morceaux de mémoire ne sont plus accessibles à partir de votre code et en renvoyant ces morceaux au magasin gratuit.

EDIT: Oui, le lien est pour C #, mais C # et Java sont identiques à cet égard.

Billy ONeal
la source
Il y a en fait une question sur SO sur la différence entre java et le GC de C #: stackoverflow.com/questions/492703/c-vs-java-garbage-collector
NullUserException
3

Beaucoup de gens pensent que le ramasse-miettes collecte et élimine les objets morts.
En réalité, le garbage collection Java fait le contraire! Les objets vivants sont suivis et tout le reste est désigné comme des déchets.

Lorsqu'un objet n'est plus utilisé, le garbage collector récupère la mémoire sous-jacente et la réutilise pour une future allocation d'objets. Cela signifie qu'il n'y a pas de suppression explicite et qu'aucune mémoire n'est restituée au système d'exploitation. Pour déterminer quels objets ne sont plus utilisés, la JVM exécute par intermittence ce que l'on appelle très justement un algorithme de marquage et de balayage.

Vérifiez ceci pour plus d'informations: http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx

VdeX
la source
1

Pour le dire dans les termes les plus simples que même un non-programmeur peut comprendre, lorsqu'un programme traite des données, il crée des données intermédiaires et un espace de stockage (variables, tableaux, certaines métadonnées d'objets, etc.) pour ces données.

Lorsque ces objets sont accessibles via des fonctions ou sur une certaine taille, ils sont alloués à partir d'un tas central. Ensuite, lorsqu'ils ne sont plus nécessaires, ils doivent être nettoyés.

Il y a de très bons articles en ligne sur la façon dont cela fonctionne, donc je vais juste couvrir la définition très basique.

Le GC est essentiellement la fonction qui effectue ce nettoyage. Pour ce faire, il efface les entrées de table qui ne sont référencées par aucun objet actif, ce qui supprime effectivement les objets, puis copie et compacte la mémoire. C'est un peu plus compliqué que ça, mais vous voyez l'idée.

Le gros problème est que certaines parties de ce processus nécessitent souvent l'arrêt temporaire de l'ensemble de la machine virtuelle Java, ainsi que l'ensemble du processus étant très gourmand en processeur et en bande passante mémoire. Les différentes options de GC et les options de réglage pour chacun sont conçues pour équilibrer ces divers problèmes avec l'ensemble du processus de GC.

Robert Wm Ruedisueli
la source
0

Le nettoyage de la mémoire en Java (et dans d'autres langages / plates-formes) est un moyen pour l'environnement d'exécution java (JRE) de réutiliser la mémoire d'objets java qui ne sont plus nécessaires. De manière simpliste, lorsque le JRE démarre initialement, il demande au système d'exploitation (O / S) une certaine quantité de mémoire. Lorsque le JRE exécute vos applications, il utilise cette mémoire. Lorsque votre application a fini d'utiliser cette mémoire, le "Garbage Collector" du JRE arrive et récupère cette mémoire pour une utilisation par différentes parties de vos applications existantes. Le "Garbage Collector" du JRE est une tâche d'arrière-plan qui est toujours en cours d'exécution et tente de sélectionner les moments où le système est inactif pour effectuer ses exécutions de déchets.

Une analogie du monde réel serait les éboueurs qui viennent chez vous et ramassent vos déchets recyclables ... éventuellement, ils sont réutilisés d'une autre manière par vous-même et / ou d'autres personnes.

Al Dass
la source
0

Le garbage collector peut être considéré comme un gestionnaire de comptage de références. si un objet est créé et que sa référence est stockée dans une variable, son nombre de références est augmenté de un. au cours de l'exécution si cette variable est affectée à NULL. le nombre de références pour cet objet est décrémenté. donc le nombre de références actuel pour l'objet est 0. Maintenant, lorsque le garbage collector est exécuté, il vérifie les objets avec le nombre de références 0. et libère les ressources qui lui sont allouées.

L'appel du garbage collector est contrôlé par les stratégies de garbage collection.

Vous pouvez obtenir des données ici. http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html

bala sreekanth
la source
1
Le comptage de références est une mauvaise façon de mettre en œuvre GC. Je ne pense pas qu'une implémentation JVM majeure l'utilise.
NullUserException le
0

Le garbage collector est un composant de jvm.

Il est utilisé pour collecter les ordures chaque fois que le processeur est libre.

Ici, garbage signifie objets inutilisés qu'il exécute en arrière-plan du programme principal

pour surveiller l'état du programme principal.

Pulipati Prasadarao
la source
0

Le garbage collection automatique consiste à examiner la mémoire du tas, à identifier les objets utilisés et ceux qui ne le sont pas, et à supprimer les objets inutilisés. Un objet en cours d'utilisation ou un objet référencé signifie qu'une partie de votre programme conserve toujours un pointeur vers cet objet. Un objet inutilisé, ou un objet non référencé, n'est plus référencé par aucune partie de votre programme. Ainsi, la mémoire utilisée par un objet non référencé peut être récupérée.

Dans un langage de programmation comme C, l'allocation et la désallocation de mémoire est un processus manuel. En Java, le processus de désallocation de la mémoire est géré automatiquement par le garbage collector. Veuillez vérifier le lien pour une meilleure compréhension. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Shashank Shankaranand
la source
0

Le garbage collection fait référence au processus de libération automatique de la mémoire sur le tas en supprimant les objets qui ne sont plus accessibles dans votre programme. Le tas est une mémoire appelée stockage libre, qui représente un grand pool de mémoire inutilisée allouée à votre application Java.

Aamir M Meman
la source
1
N'utilisez pas la mise en forme des guillemets pour le texte qui n'est pas cité, et s'il est cité, vous devez citer la source.
Marquis de Lorne
0

Les principes de base du garbage collection sont de trouver des objets de données dans un programme qui ne seront plus accessibles à l'avenir et de récupérer les ressources utilisées par ces objets. https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29

Avantages

1) Sauvegarde des bogues, qui se produisent quand une partie de la mémoire est libérée alors qu'il y a encore des pointeurs vers elle, et l'un de ces pointeurs est déréférencé. https://en.wikipedia.org/wiki/Dangling_pointer

2) Double bogues libres, qui se produisent lorsque le programme tente de libérer une région de mémoire qui a déjà été libérée, et peut-être déjà été allouée à nouveau.

3) Empêche certains types de fuites de mémoire, dans lesquelles un programme ne parvient pas à libérer la mémoire occupée par des objets devenus inaccessibles, ce qui peut entraîner un épuisement de la mémoire.

Désavantages

1) Consommation de ressources supplémentaires, impacts sur les performances, possibles blocages dans l'exécution du programme et incompatibilité avec la gestion manuelle des ressources. Le garbage collection consomme des ressources informatiques pour décider de la mémoire à libérer, même si le programmeur peut déjà avoir connu ces informations.

2) Le moment où les déchets sont effectivement collectés peut être imprévisible, entraînant des blocages (pauses pour changer / libérer de la mémoire) dispersés tout au long d'une session. Les blocages imprévisibles peuvent être inacceptables dans les environnements en temps réel, dans le traitement des transactions ou dans les programmes interactifs.


Tutoriel Oracle http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Le garbage collection est le processus qui identifie les objets utilisés et ceux qui ne le sont pas, et supprime les objets inutilisés.

Dans un langage de programmation comme C, C ++, l'allocation et la libération de mémoire est un processus manuel.

int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory

La première étape du processus s'appelle le marquage. C'est là que le ramasse-miettes identifie les morceaux de mémoire utilisés et ceux qui ne le sont pas.

Étape 2a. La suppression normale supprime les objets non référencés en laissant des objets référencés et des pointeurs vers de l'espace libre.

Pour améliorer les performances, nous souhaitons supprimer les objets non référencés et également compacter les objets référencés restants. Nous souhaitons conserver les objets référencés ensemble, il sera donc plus rapide d'allouer une nouvelle mémoire.

Comme indiqué précédemment, devoir marquer et compacter tous les objets dans une JVM est inefficace. Au fur et à mesure que de plus en plus d'objets sont alloués, la liste des objets augmente et augmente, ce qui entraîne un temps de nettoyage de la mémoire de plus en plus long.

Continuez à lire ce didacticiel et vous saurez comment GC relève ce défi.

En bref, il existe trois régions du tas, YoungGeneration pour les objets à durée de vie courte, OldGeneration pour les objets à longue période et PermanentGeneration pour les objets qui vivent pendant la vie de l'application, par exemple, les classes, les bibliothèques.

Yan Khonski
la source
0

Comme les objets sont alloués dynamiquement par le nouvel opérateur, vous pouvez demander comment ces objets sont détruits et comment la mémoire occupée est libérée. Dans d'autres langages tels que C ++, vous devez libérer dynamiquement les objets alloués manuellement par l'opérateur de suppression. Java a une approche différente; il gère automatiquement la désallocation. La technique est connue sous le nom de Garbage Collection .

Cela fonctionne comme ceci: lorsqu'il n'y a pas de références à un objet, on suppose que cet objet n'est plus nécessaire et vous pouvez récupérer la mémoire occupée par l'objet. Il n'est pas nécessaire de détruire explicitement les objets comme en C ++. Le nettoyage de la mémoire se produit sporadiquement pendant l'exécution du programme; Cela ne se produit pas simplement parce qu'il y a un ou plusieurs objets qui ne sont plus utilisés. En outre, plusieurs implémentations d'exécution Java ont des approches différentes de la récupération de place, mais la plupart des programmeurs n'ont pas à s'en soucier lors de l'écriture de programmes.

Amarildo
la source
-2

Le garbage collection automatique est un processus dans lequel la machine virtuelle Java supprime ou conserve certains points de données en mémoire afin de libérer de l'espace pour le programme en cours d'exécution. La mémoire est d'abord envoyée à la mémoire du tas, c'est là que le garbage collector (GC) fait son travail, puis il est décidé de s'arrêter ou de la conserver. Java suppose que le programmeur ne peut pas toujours être fiable, il met donc fin aux éléments dont il pense ne pas avoir besoin.

Lopes_CP_2579
la source