Question

Quelles sont les racines du ramasse-miettes?

J'ai lu la définition de root comme "toute référence à laquelle votre programme peut accéder" et la définition de live est un objet qui est utilisé, qui peut être une variable locale, une variable statique.

Je suis peu confus avec la distinction entre les objets racine et les objets vivants.

Qu'est-ce que le chemin d'accès à la racine?Comment fonctionnent les objets root et live?

Quelqu'un peut-il élaborer?

Était-ce utile?

La solution

Si vous considérez les objets en mémoire comme un arbre, les "racines" seraient les nœuds racine - chaque objet immédiatement accessible par votre programme.

Person p = new Person();
p.car = new Car(RED);
p.car.engine = new Engine();
p.car.horn = new AnnoyingHorn();

Il y a quatre objets; une personne, une voiture rouge, son moteur et son klaxon. Dessinez le graphique de référence:

     Person [p]
        |
     Car (red)
   /           \
Engine    AnnoyingHorn

Et vous vous retrouverez avec Person à la "racine" de l'arbre. Il est en direct car il est référencé par une variable locale, p, que le programme peut utiliser à tout moment pour faire référence à l'objet Person. Cela vaut également pour les autres objets, via p.car, p.car.engine, etc.

Étant donné que Person et tous les autres objets qui lui sont connectés de manière récursive sont en direct, il y aurait des problèmes si le GC les collectait.

Considérez cependant si ce qui suit est exécuté après un certain temps:

p.car = new Car(BLUE);

Et redessinez le graphique:

     Person [p]
        |
     Car (blue)       Car (red)
                    /           \
                Engine    AnnoyingHorn

Maintenant, le Person est accessible via p et la voiture bleue via p.car, mais il est impossible d'accéder à nouveau à la voiture rouge ou à ses pièces - elles ne sont pas connectées à une racine en direct. Ils peuvent être collectés en toute sécurité.

Il s'agit donc vraiment de prendre chaque point de départ (chaque variable locale, globales, statiques, tout dans les autres threads et cadres de pile) - chaque racine - et de suivre récursivement toutes les références pour constituer une liste de tous les "live "objets: objets en cours d'utilisation et impropres à la suppression. Tout le reste est à la poubelle, en attente d'être ramassé.

Autres conseils

Les racines GC (Garbage Collector) sont des objets spéciaux pour le garbage collector. Le garbage collector collecte les objets qui ne sont pas des racines GC et qui ne sont pas accessibles par des références à partir des racines GC.

Il existe plusieurs types de racines GC. Un objet peut appartenir à plus d'un type de racine. Les types de racine sont:

  • Classe - classe chargée par le chargeur de classe système. De telles classes ne peuvent jamais être déchargées. Ils peuvent contenir des objets via des champs statiques. Veuillez noter que les classes chargées par les chargeurs de classes personnalisés ne sont pas des racines, à moins que les instances correspondantes de java.lang.Class ne soient des racines d'autres types.
  • Fil de discussion - fil en direct
  • Stack Local - variable locale ou paramètre de la méthode Java
  • JNI Local - variable locale ou paramètre de la méthode JNI
  • JNI Global - référence JNI globale
  • Moniteur utilisé - objets utilisés comme moniteur pour la synchronisation
  • Détenu par JVM - objets détenus par le garbage collection par JVM pour ses besoins. En fait, la liste de ces objets dépend de l'implémentation JVM. Les cas connus possibles sont: le chargeur de classe système, quelques classes d'exceptions importantes que la JVM connaît, quelques objets pré-alloués pour la gestion des exceptions et des chargeurs de classes personnalisés lorsqu'ils sont en train de charger des classes. Malheureusement, JVM ne fournit absolument aucun détail supplémentaire pour ces objets. C'est donc à l'analyste de décider à quel cas appartient un certain "Tenu par JVM".

(crédit au site Web de YourKit )

Le fait que YourKit ne mentionne pas le fait que les objets en attente de finalisation seront conservés en tant que racines jusqu'à ce que le GC exécute la méthode finalize(). Cela peut provoquer une rétention transitoire de grands graphiques de manière quelque peu inattendue. La règle générale est de ne pas utiliser de finaliseurs (mais c'est une question différente).

Les racines ou racines de garbage collection sont les objets qui sont toujours accessibles . Si un objet est toujours accessible, il n'est pas éligible pour le garbage collection; les racines sont donc toujours inéligibles à la collecte. Il s'agit de l'ensemble initial d'objets à partir duquel l'accessibilité de tous les autres objets du tas est déterminée.

Les autres objets sur le tas accessibles à partir des racines du ramasse-miettes sont considérés comme des objets vivants et ne peuvent pas être collectés; les objets inaccessibles peuvent être marqués pour la récupération.

Je connais mieux Java que la plate-forme .Net, je ne parlerai donc que pour une seule. Sur la plate-forme Java, les racines GC dépendent en fait de l'implémentation. Dans la plupart des environnements d'exécution cependant, les racines GC ont tendance à être les opérandes de la pile (car ils sont actuellement utilisés par les threads) et les membres de classe (statiques) des classes. L'accessibilité est calculée à partir de ces objets dans la plupart des JVM. Il existe d'autres cas où les paramètres locaux et les opérandes utilisés par les appels JNI seront considérés comme faisant partie de l'ensemble racine, et également utilisés pour calculer l'accessibilité.

J'espère que cela dissipera tous les doutes persistants sur ce qu'est une racine (ensemble) et ce qu'est un objet vivant.

Le site Web IBM répertorie les éléments suivants comme racines GC.

Notez que certaines d'entre elles sont des constructions artificielles faites par un analyseur de mémoire, mais il est toujours important d'être conscient si vous regardez un vidage de tas.

  • Classe système

    Une classe chargée par le chargeur d'amorçage ou le chargeur de classe système. Par exemple, cette catégorie inclut toutes les classes du fichier rt.jar (qui fait partie de l'environnement d'exécution Java), telles que celles du package java.util. *.

  • JNI local

    Une variable locale en code natif, par exemple du code JNI défini par l'utilisateur ou du code interne JVM.

  • JNI global

    Une variable globale en code natif, par exemple du code JNI défini par l'utilisateur ou du code interne JVM.

  • Bloc de discussion

    Un objet référencé à partir d'un bloc de thread actif.

  • < gagnantThread

    Un fil de discussion en cours.

  • Moniteur occupé

    Tout ce qui a appelé les méthodes wait () ou notify (), ou qui est synchronisé, par exemple en appelant la méthode synchronized (Object) ou en entrant une méthode synchronized. Si la méthode était statique, la racine est une classe, sinon c'est un objet.

  • Java local

    Une variable locale. Par exemple, des paramètres d'entrée ou des objets de méthodes créés localement qui sont toujours dans la pile d'un thread. Pile native

    Paramètres d'entrée ou de sortie en code natif, par exemple code JNI défini par l'utilisateur ou code interne JVM. De nombreuses méthodes ont des parties natives et les objets gérés en tant que paramètres de méthode deviennent des racines de garbage collection. Par exemple, les paramètres utilisés pour les opérations de fichier, de réseau, d'E / S ou de réflexion.

  • < finalFinalizer

    Un objet qui se trouve dans une file d'attente, en attente de l'exécution d'un finaliseur.

  • <₹ Non finalisé

    Un objet qui a une méthode finalize, mais qui n'a pas été finalisé et qui n'est pas encore dans la file d'attente du finaliseur.

  • Un objet inaccessible depuis toute autre racine, mais qui a été marqué comme racine par Memory Analyzer afin que l'objet puisse être inclus dans une analyse.

    Les objets inaccessibles sont souvent le résultat d'optimisations de l'algorithme de ramasse-miettes. Par exemple, un objet peut être un candidat pour le garbage collection, mais être si petit que le processus de garbage collection serait trop coûteux. Dans ce cas, l'objet peut ne pas être récupéré et rester comme un objet inaccessible.

    Par défaut, les objets inaccessibles sont exclus lorsque Memory Analyzer analyse le vidage du tas. Ces objets ne sont donc pas affichés dans l'histogramme, l'arbre du dominateur ou les résultats de la requête. Vous pouvez modifier ce comportement en cliquant sur Fichier> Préférences ...> IBM Diagnostic Tools for Java - Memory Analyzer, puis en cochant la case Conserver les objets inaccessibles.

  • Cadre de pile Java

    Un cadre de pile Java, qui contient des variables locales. Ce type de racine de garbage collection n'est généré que si vous définissez les préférences pour traiter les cadres de pile Java comme des objets. Pour plus d'informations, consultez Principes de base de Java: Threads et requêtes de pile de threads.

  • <❯Inconnu

    Un objet de type racine inconnu. Certains vidages, tels que les fichiers IBM Portable Heap Dump (.phd), n'ont pas d'informations sur la racine. Dans ce cas, l'analyseur de mémoire marque les objets qui n'ont aucune référence entrante ou qui sont inaccessibles à partir de toute autre racine, comme inconnus. Cette action garantit que l'analyseur de mémoire conserve tous les objets dans le vidage.

En java, je dirais que les threads sont les objets racine.Chaque objet vivant peut être retracé sur un thread en direct.Par exemple, un objet statique est référencé par une classe, qui est référencée par un chargeur de classe, qui est référencée par une autre classe, qui est référencée par une instance de cette classe, ... qui est référencée par un Runnable, qui est référencépar un fil en direct.( Remarque, les classes peuvent être GC, elles ne peuvent pas être des racines )

Nous pouvons également considérer une "vraie" racine pour tous les threads, mais cela est hors du domaine de Java standard.Nous ne pouvons pas dire ce que c'est et comment il fait référence à tous les fils.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top