Je suivez un objet en utilisant Alors maintenant, je me demande, quand exactement "la mise à zéro" du Maintenant, je me demande aussi si peut-être affaiblie
foo code>. Cette classe a un destructeur dans lequel j'ai besoin d'accéder à cet objet suivi. L'objet i Track suive également
FOO code> à l'aide de
faiblicielle
faiblice code> se produit? Est-ce que tout
affaiblie code> est annulé avant que tout finisseur ne soit exécuté ou que chacun d'entre eux soit annulé juste avant que le finaliseur de l'objet qu'ils suivent est sur le point de courir? P>
mono code> peut éclairer celui-ci ( lien 1 , link 2 ). Mais je suis un peu inquiet que, peut-être que
ms gc code> et
mono gc code> peut aborder ce problème différemment et être incompatible em>. P>.
3 Réponses :
Vous pouvez vérifier par vous-même avec un simple programme de test. Mais je trouve la documentation pour le type code> type code> soit un peu plus clair que la page que vous regardiez. P>
En particulier, le drapeau appelé "court" et "long" dans votre page liée est appelé Indique quand arrêter de suivre l'objet. Si vrai, l'objet est suivi après la finalisation; Si FAUX, l'objet n'est suivi que jusqu'à la finalisation. P>
blockQuote>
La section "remarques" lit également: p>
Si la trackResurrection est fausse, une référence faible faible est créée. Si la trackresurrection est vraie, une longue référence faible est créée. P>
blockQuote>
Ceci confirme que lorsque vous utilisez une référence faible «courte», un objet finalisé ne sera plus suivi (c.-à-d. La cible Pour les deux types de référence faible, un objet qui a été recueilli à la poubelle ne sera certainement plus suivi (évidemment). P>
En général, aucun autre thread dans votre programme ne devrait être capable d'observer un objet lorsque le thread de finaliseur fait réellement son travail, de sorte que le moment précis de la référence "courte" faible lorsque la cible TrackResurrection code> dans la documentation du constructeur actuel . Et la description du paramètre lit: p>
code> devient
null code>) par le
) Affectement code> objet, mais lorsque vous utilisez une "longue" référence faible, ce sera. P>
code> propriété est définie sur
null code> semble sans intérêt pour moi. Si un autre thread dans votre programme observe la valeur non nulle, le finaliseur n'a pas encore été exécuté. Si elle l'observe comme nul, le finaliseur a couru. Ce « autre thread » ne doit pas exécuter lui-même alors que le thread finaliseur travaille, donc la finalisation devrait être essentiellement atomique dans la mesure où « l'autre thread » est concerné. P>
Je pensais écrire un petit programme de démonstration qui démontre la différence. S'est avéré être un peu plus difficile que je comptais. Le premier ingrédient nécessaire consiste à garantir le ralentissement du filetage de finaliseur afin que vous puissiez observer la valeur de faiblesseReReference.Inalive sans risquer d'être affectée par une course avec le fil de finalisation. Donc j'ai utilisé: puis une petite classe qui sera la cible de la faiblesseFerence: p> alors un programme qui démontre la différence entre Référence longue et faible faible: p> Vous devez exécuter ce programme afin que le débogueur ne puisse affecter la durée de vie des objets. Sélectionnez la version de déverrouillage et modifiez un paramètre de débogueur: Outils + Options, débogage, Général, décanter l'option «Supprimer Jit Optimization». P> a révélé que l'ordre de finalisation des objets n'est vraiment pas déterministe. La commande est différente chaque fois que vous exécutez le programme. Nous voulons que l'objet FinalistierDelayer soit finalisé en premier, mais cela ne se produit pas toujours. Je pense em> il s'agit d'un effet secondaire sur la fonctionnalité de randomisation de la mise en page d'espace d'adresse intégrée, il rend le code géré très difficile à attaquer. Mais courir assez souvent et vous obtiendrez éventuellement: p> Délai de retarder ... longue histoire courte: p> méfiez-vous d'une bizarrerie lorsque l'objet est ressuscité, replacé de la file d'attente à fragilité à l'enceinte normale lorsqu'une référence forte est recréée. Pas quelque chose que j'ai exploré dans ce programme de démonstration, mais une longue référence faible sera nécessaire pour observer cela. La raison de base pour laquelle vous auriez besoin d'une longue référence faible. P> p>
Court alive = faux
Long alive = vrai
Retard fait
Exemple 1 Finalisé
Exemple 2 Finalized
Finalisation effectuée
Longue vivance = faux
p>
blockQuote>
Donc après de nombreuses recherches, j'ai pu trouver cet article ancien Collection ordures Partie 2: Gestion automatique de la mémoire dans le cadre Microsoft .NET ( 1 discute de la résurrection et de la file d'attente fragile): P>
Maintenant, voici ce qui se passe lorsqu'une collection de déchets (GC) fonctionne: p>
Le collecteur des ordures construit un graphique de tous les objets accessibles. strong> Partie 1 de cet article discuté de la manière dont cela fonctionne. P> LI>
Le collecteur des ordures scanne la courte table de référence faible. Si un pointeur dans la table fait référence à un objet qui ne fait pas partie du graphique fort>, le pointeur identifie un objet inaccessible et la fente dans la table de référence faibles courte est définie sur NULL forte>. p> li>
Le collecteur des ordures scanne la file d'attente de finalisation forte>. Si un pointeur de la file d'attente fait référence à un objet qui ne fait pas partie du graphique, le pointeur identifie un objet inaccessible et le pointeur est déplacé de la file d'attente de finalisation à la file d'attente à fragilité. À ce stade, l'objet est ajouté au graphique car l'objet est maintenant considéré comme accessible. P> li>
Le collecteur des ordures scanne la longue table de référence faible. Si un pointeur dans la table fait référence à un objet qui ne fait pas partie du graphique (qui contient maintenant les objets pointés par des entrées dans la file fragile), le pointeur identifie un objet inaccessible et l'emplacement est défini sur NULL. p> li>
Le collecteur des ordures compacte la mémoire, pressant les trous laissés par les objets inaccessibles. P> li> ol> blockQuote>
Alors même si ma classe
FOO code> a un finisseur et donc, il sera donc dans une file fragile (qui est considérée comme une racine) - la résolution de faibles références faibles arrive avant que cet objet ne soit enraciné Dans la file fragile, ce qui signifie que la référence faible faible sera NULL: p>
Le collecteur de déchets Définit le pointeur sur NULL dans la table de référence faibles courte dès qu'il a déterminé que l'objet est inaccessible. Si l'objet a une méthode de finalisation, la méthode n'a pas encore été appelée afin que l'objet existe toujours. Si l'application accède à la propriété cible de l'objet affairé, alors NULL sera renvoyé même si l'objet existe toujours. p> blockQuote>
En outre, comme mentionné sur Weblog Yun Jin's's Weblog < / a>, il n'est généralement pas bon de faire référence à des objets finalisables dans les finaliseurs, mais
faim librable code> est un peu une exception (bien que Ce n'était pas toujours le cas ). Etant donné que
affaibleur code> est un objet avec le finaliseur, s'il est accédé à la finaliseur de
FOO code>, il aurait peut-être été déjà finalisé (auquel cas la propriété
cible code> retournera toujours NULL, malgré le fait que l'objet suivi pourrait toujours être alive et bien ( Plus d'infos ). P >
Je viens de confirmer que ordures mono Collector est cohérent avec ce comportement. P>
Référence utile:
- faim de la source code source
- afférencecode source p>
"Depuis que l'affaiblissement est un objet avec le finaliseur" i> - es-tu toujours sûr que vous êtes sur la bonne voie ici?
@Henkoleshterman, il complique beaucoup les choses par beaucoup, mais j'espère que je peux travailler autour de cela en quelque sorte. Par exemple, en héritant d'une faiblesse de la logique fantaisie, j'ai besoin de là. :-) L'ordre de ce que GC fait est absolument crucial de bien réussir.
Wow, c'est une documentation déroutante ... c'est looks i> comme la petite documentation de référence faibles devait parler de la finalisation, pas de la collecte des ordures - mais ce n'est pas clair.
Je suis allé chercher à travers l'ancien code source SSCLI pour essayer de voir ce que je pouvais trouver. N'a rien trouvé encore, mais a trouvé un commentaire intrigant à l'intérieur de la cible code> getter code>: "ne devrait se produire que lorsqu'il est utilisé illégalement, comme utiliser une faiblence d'un finaliseur" - peut-être que ce que vous essayez de faire est condamné quand même.
Pas une réponse, mais il convient de noter que vous devriez généralement éviter les destructeurs et c'est probablement un problème XY.
@HENKHOLTERMAN, je suis en train de mettre en œuvre un dictionnaire faible qui devrait automatiquement nettoyer les références faibles annulées. Je peux difficilement imaginer comment vous pourriez faire cela sans destructeurs.
Les choses qui ont besoin de nettoyer ne doivent pas être placées dans un dictionnaire faible.
J'ai dit des références annulées. Comme dans
faim de faim code> aux éléments réels, mais depuis que ceux-ci ont été collectés, le
faibl libérant.target code> est maintenant null. Cependant, l'objet
faim code> est toujours dans le dictionnaire et gaspille de l'espace.