Maison  >  Article  >  Java  >  Explication détaillée du marquage des objets recyclés en Java et du processus de marquage secondaire des objets

Explication détaillée du marquage des objets recyclés en Java et du processus de marquage secondaire des objets

黄舟
黄舟original
2017-10-11 10:12:431709parcourir

Cet article présente principalement le contenu pertinent du marquage des objets de recyclage Java et le processus de marquage secondaire des objets. L'éditeur pense que c'est plutôt bien. Je le partagerai avec vous ici. Les amis qui en ont besoin peuvent s'y référer.

1. Marquage des objets

1. Qu'est-ce qu'une marque ? Comment marquer ?

Je crois que tout le monde connaît la première question. Le marquage consiste à marquer certains objets morts pour faciliter le nettoyage de la poubelle. Quant à la manière de marquer, il existe généralement deux méthodes : le comptage de références et l'analyse d'accessibilité.

Le comptage de références est relativement simple à mettre en œuvre. Il s'agit d'ajouter un compteur de références à l'objet. Chaque fois qu'il y a une référence à celui-ci, il sera augmenté de 1. Lorsque la référence est invalide, elle sera augmentée. sera décrémenté de 1. Lorsque le compteur est à 0, marqué pour le recyclage. Ce jugement est très efficace, mais de nombreuses machines virtuelles grand public n'utilisent pas cette méthode, principalement parce qu'il est difficile de résoudre le problème des références circulaires entre plusieurs objets. Même si elle n'est pas beaucoup utilisée, elle vaut quand même la peine d'être apprise !


public class Test {
private Object obj;
Public static void main(){
Test t1=new Test();
Test t2=new Test();
t1.obj=t2;
t2.obj=t1;
t1=null;
t2=null;
//如果对象在这行发生gc,那么t1和t2对象是否能被回收
System.gc();
}
}

L'idée de base de l'analyse d'accessibilité est la suivante : en utilisant certains objets appelés "GC Roots" comme point de départ, commencez la recherche à partir de ces nœuds , recherchez des objets qui ont une relation de référence directe ou indirecte avec le nœud, et combinez ces objets sous forme de chaînes pour former un « réseau de relations », également appelé chaîne de référence. Enfin, le garbage collector collecte certains objets qui ne font pas partie de ce réseau de relations. Comme le montre l'image :

L'objet connecté à l'objet GC Roots est un objet qui est définitivement encore vivant, et l'objet dé à droite n'a rien à voir avec GCROOTS, ce sera donc marqué comme objet recyclable. Actuellement, les machines virtuelles commerciales grand public utilisent des méthodes similaires. Alors, quels objets peuvent être utilisés comme « racines GC » ? En Java, il existe quatre types d'objets qui peuvent être utilisés comme objets de référence dans "GC Roots"

1 : Stack frame (nom au chapitre 1). (Dans la pile)

2 : Objet référencé par des propriétés statiques. (Dans la zone méthode)

3 : Objet référencé par constante. (Dans la zone méthode)

4 : Objet référencé par JNI dans la pile de méthodes locale. (Dans la pile de méthodes locale)

2. Recyclage secondaire des objets

J'ai dit que l'objet est marqué, mais ce n'est pas le cas signifie qu'il est marqué. Sera-t-il définitivement recyclé ? Je ne sais pas si vous vous souvenez que la classe Object a une méthode finalize(). Toutes les classes héritent de la classe Object, cette méthode est donc implémentée par défaut.

Le principe de fonctionnement de finalize devrait être le suivant : une fois que le ramasse-miettes est prêt à libérer l'espace de stockage occupé par l'objet, il appelle d'abord finalize(), et seulement lors du prochain processus de ramasse-miettes. , cela va-t-il vraiment récupérer la mémoire de l'objet. Donc, si vous utilisez finalize(), vous pouvez effectuer un travail de nettoyage ou de nettoyage important pendant le ramasse-miettes
Quand finalize() est-il appelé ?

<.>Il existe trois situations

1. Tous les objets sont automatiquement appelés lorsqu'ils sont récupérés, par exemple lors de l'exécution de System.gc().


2. Le programme se termine. La méthode finalize est appelée une fois pour chaque objet.


3. Appeler explicitement la méthode finalize


Le but de cette méthode est : avant que l'objet ne soit recyclé, la méthode finalize() de l'objet sera appelée. . Le recyclage fait référence ici après avoir été marqué. Le problème réside ici. Existe-t-il une situation où un objet n'est plus dans le "réseau de relations" (chaîne de référence) mentionné dans le chapitre précédent, mais après que le développeur a réécrit la finalisation. (), et a rajouté l'objet au « réseau de relations », c'est-à-dire que l'objet nous est toujours utile et ne doit pas être recyclé, mais il a été marqué. Que devons-nous faire ?

Pour résoudre ce problème, l'approche de la machine virtuelle consiste à marquer les objets deux fois, c'est-à-dire à marquer pour la première fois les objets qui ne sont pas dans le « réseau de relations ». Pour la deuxième fois, il faut d'abord déterminer si l'objet a implémenté la méthode finalize(). S'il n'a pas été implémenté, il sera directement déterminé que l'objet est recyclable s'il a été implémenté, il sera placé ; dans une file d'attente d'abord, et un niveau bas créé par la machine virtuelle l'exécutera, puis un deuxième marquage à petite échelle sera effectué. Cette fois l'objet marqué sera effectivement recyclé.


Résumé : Pour faire simple, l'objet est marqué pour la première fois, et la méthode finalize() de l'objet sera exécutée avant le prochain GC. Lors de l'exécution de la méthode finalize(), il est jugé si l'objet a implémenté la méthode finalize(). S'il n'est pas implémenté, il est effacé directement s'il est implémenté, l'objet est placé dans une file d'attente pour exécuter la méthode finalize ; et marqué pour la deuxième fois
dans l'algorithme de recherche racine Java Pour déterminer l'accessibilité des objets, les objets inaccessibles ne doivent pas nécessairement être nettoyés. Il y a une période de probation à ce moment-là. Pour vraiment juger qu'un objet est mort, il doit passer par au moins deux processus de marquage : Si l'objet constate qu'il n'y a pas de chaîne de référence associée aux racines GC après avoir effectué une recherche de racine, il le fera. être marqué pour la première fois et marqué. Une fois filtré, la condition de filtrage est de savoir s'il est nécessaire que cet objet exécute la méthode finalize() Lorsque l'objet ne couvre pas la méthode finalize(), ou la méthode finalize(. ) a été appelée par la machine virtuelle , la machine virtuelle sera dans tous les cas considérée comme "Il n'est pas nécessaire d'exécuter ".

C'est-à-dire que lorsqu'un objet remplace la méthode finalize(), l'objet est jugé nécessaire pour exécuter la méthode finalize(), puis l'objet est placé dans la file d'attente F-Queue, et Il sera exécuté ultérieurement par un thread Finalizer de faible priorité créé automatiquement par la machine virtuelle. Ce qu'on appelle ici l'exécution signifie que la machine virtuelle démarre cette méthode, mais ne promet pas d'attendre la fin de son exécution. La raison en est : si un objet s'exécute lentement dans la méthode finalize(), ou si une boucle infinie se produit (dans des cas extrêmes), cela peut amener d'autres objets de la file d'attente F-Queue à être en attente permanente, ou même provoquer toute la mémoire du système de recyclage plante. La méthode finalize() est la dernière chance pour l'objet d'échapper au sort de la mort. Plus tard, le GC marquera l'objet dans la file d'attente F pour une seconde petite échelle si l'objet veut réussir à se sauvegarder dans finalize(). ---- tant qu'il suffit de le réassocier à quoi que ce soit sur la chaîne de référence, il sera alors supprimé de la collection "sur le point d'être recyclé" lorsqu'il sera marqué pour la deuxième fois si l'objet ne s'échappe pas à ce moment-là ; temps, il sera recyclé. Exemple de code : reportez-vous au chapitre correspondant de « Compréhension approfondie de la machine virtuelle Java »

Résumé

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn