Autant que je sache, GC commence par un ensemble d'objets initiaux (pile, objets statiques) et traverse récursivement qu'il construit un graphique d'objets accessibles. Ensuite, il marque la mémoire prise par ces objets comme occupé et suppose tout le reste de la mémoire libre. p>
Mais si cette mémoire "GRATUIT" contient un objet avec Je suppose que GC peut garder une trace de tous les objets «finalisables» pendant qu'ils sont vivants. Si tel est le cas, d'avoir des objets finalisables fabriquent des ordures collectant plus cher même quand ils sont encore en vie? P> finaliser la méthode "/ code>? GC doit l'appeler, mais je ne vois pas comment il peut même savoir sur des objets qui ne sont plus accessibles. P>
4 Réponses :
La méthode finaliser code> est appelée lorsqu'un objet est
finaliser code> à ce sujet. Il n'est pas nécessaire de garder une trace des objets à finaliser. P>
mais que si cette mémoire "libre" contient un objet avec finaliser méthode? GC doit l'appeler, mais je ne vois pas comment cela peut même savoir objets qui ne sont plus accessibles. p> blockQuote>
Disons que nous utilisons le collecteur de déchets CMS. Après avoir marqué avec succès tous les objets en direct dans une première phase, il numérisera à nouveau la mémoire et supprimera tous les objets morts. Le thread GC n'appelle pas
finaliser la méthode code> directement pour ces objets. P>
Lors de la création, ils sont enveloppés et ajoutés à la file d'attente finaliseur par JVM (voir
java.lang.ref.finalizer.register (objet) code>). Cette file d'attente est traitée dans un autre thread (
java.lang.ref.finalizer.finalizeThread code>),
finaliser la méthode sera appelé quand il n'y a pas de références à l'objet. Plus de détails sont couverts dans Ce blog post . P >
Si tel est le cas, les objets finalisables font-ils des ordures collectant plus cher même quand ils sont encore en vie? p> blockQuote>
Comme vous pouvez le voir maintenant, la plupart du temps qu'il ne le fait pas. p>
Mais comment GC trouve-t-il des objets inaccessibles? Pour autant que je sache, cela ne "voit" que des objets accessibles et tout le reste est juste "libre" mémoire. Comment GC peut-il distinguer un objet inaccessible en particulier s'il n'en a pas référence?
finaliser.register (objet) code> est appelé lorsqu'un objet avec une méthode non triviale
finaliser () code> est créé i>. L'existence du
finalisference code> créé de cette manière garantit qu'il peut être enquentage plus tard.
@Vladshevchenko gc marque des objets vivants. Chaque objet de Java a un espace réservé pour Meta Info, par exemple. Est-il accessible, combien de collections il a survécu, etc. Ensuite, GC scanne le tas et éliminer les objets qui ne sont pas marqués.
considérer le API de référence < / a>. p>
Il offre des références avec une sémantique spéciale à la GC, c'est des références faibles, douces et fantômes. Il y a simplement un autre type code> type code> de référence spéciale, pour les objets nécessitant une finalisation. P>
Maintenant, lorsque le collecteur des ordures traverse le graphique de l'objet et rencontre un tel objet de référence spécial, il ne marquera pas d'objets accessibles à travers cette référence comme fortement accessible, mais accessible avec la sémantique spéciale. Donc, si un objet n'est que finalisable accessible, la référence sera en cours, de sorte qu'un (ou l'un des) threads de finaliseur peut interroger la file d'attente et exécuter la méthode En d'autres termes, le collecteur des ordures ne traite jamais des objets entièrement inaccessibles ici. Pour appliquer une sémantique spéciale à l'accessibilité, l'objet référence em> doit être accessible, le référent peut donc être atteint à travers em> cette référence. En cas de finaliseur-accessibles, Etant donné que ce L'autre problème est qu'un objet traité par un fil de finaliseur est accessible par ce fil et peut même s'échapper, en fonction de la méthode Ce ne serait qu'un problème de performance, si la mémoire est très faible et que la prochaine collection à la poubelle devait être effectuée plus tôt pour récupérer finalement cet objet. Mais cela ne se produit pas dans la mise en œuvre de la référence (alias "hotspot" ou "openjdk"). En fait, il pourrait y avoir un finaliser () code> (c'est pas le collecteur des ordures qui appelle cette méthode). P>
finaliser.register code>
est appelé lors de la création d'un objet et crée une instance de finaliseur code> à tour de rôle, une sous-classe de < Code> finalisference code> et DROITE DANS son constructeur , il appelle une méthode
add () code> qui insérera la référence dans une liste liée mondiale. Donc, tous ces
finalisference code> sont accessibles via cette liste jusqu'à ce qu'une finalisation réelle se produise. P>
finalisference code> sera créé directement sur l'instanciation de l'objet, si sa classe déclare une méthode non triviale
finalisez () code>, il y a déjà des frais généraux dus à avoir une exigence de finalisation, même si l'objet n'a pas encore été collecté. P>
finaliser () code>. Mais la prochaine fois, cet objet devient inaccessible, l'objet de référence spécial n'existe plus, il peut donc être traité comme n'importe quel autre objet inaccessible. P>
OutofMemoryError code> tandis que les objets sont en attente dans la file d'attente finaliseur, dont le traitement pourrait rendre plus de mémoire recouvrable. Il n'y a pas de garantie que la finalisation fonctionne assez rapidement pour que vous soyez des besoins. C'est pourquoi vous ne devriez pas compter sur elle. P>
Duplicaté possible de Java - Comment Le collecteur des ordures peut-il rapidement savoir quels objets ne les ont plus références?