6
votes

Comment Java GC appelle-t-il la méthode ()?

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.

Mais si cette mémoire "GRATUIT" contient un objet avec 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.

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?


4 Réponses :


-1
votes

La méthode finaliser est appelée lorsqu'un objet est sur pour obtenir des ordures recueillies. Cela signifie que lorsque GC détermine que l'objet n'est plus référencé, il peut appeler la méthode finaliser à ce sujet. Il n'est pas nécessaire de garder une trace des objets à finaliser.


0 commentaires


3
votes

3 commentaires

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) est appelé lorsqu'un objet avec une méthode non triviale finaliser () est créé . L'existence du finalisference 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.



6
votes

considérer le API de référence < / a>.

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 type de référence spéciale, pour les objets nécessitant une finalisation.

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 finaliser () (c'est pas le collecteur des ordures qui appelle cette 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 doit être accessible, le référent peut donc être atteint à travers cette référence. En cas de finaliseur-accessibles, finaliser.register est appelé lors de la création d'un objet et crée une instance de finaliseur à tour de rôle, une sous-classe de < Code> finalisference et DROITE DANS son constructeur , il appelle une méthode add () qui insérera la référence dans une liste liée mondiale. Donc, tous ces finalisference sont accessibles via cette liste jusqu'à ce qu'une finalisation réelle se produise.

Etant donné que ce finalisference sera créé directement sur l'instanciation de l'objet, si sa classe déclare une méthode non triviale finalisez () , 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é.

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 finaliser () . 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.

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 OutofMemoryError 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.


0 commentaires