11
votes

.NET: façon de déterminer si l'objet a des références à cela?

q. est là un moyen de savoir si un objet a des "références fortes" à elle?

Raymond Chen a laissé comparer Une solution peut être possible :

Vous voulez savoir si la référence le nombre est zéro ou non nul. Pour ça, utiliser une faiblesseference.

Notes
  • J'ai un " faible référence " à l'objet (en utilisant un faiblesse ). Si j'avais un la référence forte la réponse serait immédiatement: "Oui. Vous avez une référence forte à l'objet."
  • Le collecteur des ordures expose sans réponses
  • le propriété Isalive ne peut que vous dire si Un objet a été collecté ou non. Pas s'il y a de fortes références à cela, ou non. (Un objet sans références ne peut être décollecté - le GC ne s'est pas encore entendu là)
  • Les objets dans .NET ne sont pas une référence compté
  • Tous les objets ne sont pas tous les objets doivent Implmenet the Idisposable interface < / li>
  • Tous les objets ne sont pas les miens

    code de code

    Cet exemple de code démontre les problèmes qui s'appuient sur forçant une collection de déchets et la propriété isalive faim pour déterminer si un objet a des références remarquables à cela. xxx


5 commentaires

Pourquoi avez-vous besoin de savoir cela?


"Pour cela, utilisez une faiblesseFerence" - Raymond va faire allusion à faimérer.Salive


@Tim Robinson si Isalive renvoie true Tout ce que je peux déduire est que l'objet a pas été collecté. Si Isalive renvoie false Tout ce que je peux déduire est que l'objet a été collecté. Je veux savoir si un objet a des "références fortes" à elle. Un objet avec de fortes références ne sera pas collecté, mais tous les objets non collectés ne leur ont pas de fortes références.


Pourquoi j'ai besoin de savoir ça? Je pourrais constituer quelques raisons 1. pour l'amélioration de tout type d'homme d'élargir l'horizon de la connaissance humaine 2. Je pratique une thèse sur la dégradation physique Effets d'objets fortement référencés sur la RAM DDR dans des systèmes inhérents. 3. Je veux savoir s'il est prudent d'appeler à disposer d'une connexion de base de données. 4. Je veux attraper un bug où quelqu'un référencit un objet, mais je suis sûr que personne ne devrait l'être. 5. Parce que quelqu'un d'autre a demandé, mais les gens ont refusé de répondre à la question.


Le conseil de Mark à appeler gc.collect; Wr.isalive est bon. Le seul moyen sûr de répondre "Où sont toutes les fortes références?" est d'effectuer une collection de déchets. L'alternative pourrait être de suspendre le programme, de suivre vous-même des racines de GC et de traverser les références d'objets vous-même, mais c'est ce que le GC fait de toute façon.


3 Réponses :


11
votes

Nope, non sans utiliser l'API de débogueur.

Comme vous le dites, les objets ne font pas référence à compter ... Donc, la seule façon de découvrir serait de ramper le tas, qui arrive normalement dans le cadre de la collecte des ordures.

Notez que même après qu'il n'y ait aucune "normale" de solides références, l'objet pourrait être ressuscité dans le cadre de la finalisation de toute façon - efficacement, la file d'attente finaliseur en fait une référence si elle a un finaliseur. Peut-être que vous ne voudriez pas inclure l'objet comme "Référence - moins" dans cette situation de toute façon.


5 commentaires

"Non" était la réponse que j'ai supposée. Nous verrons si quelqu'un est en désaccord. Mais avec vous 205k de représentant, je pense que vous allez être l'autorité à ce sujet.


Vous pouvez essayer d'ajouter une conversion implicite en objet sous forme d'affaiblissement qui le prend comme paramètre et ajoutez un compteur dans cette méthode de conversion implicite, mais toutes les autres choses qui l'obtiennent comme objet l'incrémentent également. La conversion implicite en objet pourrait également être bloquée infiniment se répéter. Les médailles d'or par point sont également importantes.


@HUSEYINTUGRULBUYUKISIK: Vous ne pouvez pas ajouter de conversion implicite sur objet , et pour être honnête, je ne vois pas comment cela aiderait. Je ne comprends pas non plus la dernière partie de votre commentaire ...


@Jonskeet est-ce à cause de la collecte des ordures? Dernière partie, je veux dire que des médailles d'or plus fréquentes ont l'air cool et que vous avez maintenu une fréquence pendant 530 médailles.


@HUSEYINTUGRULBUYUKISIK: Est-ce quoi de la collecte des ordures? L'interdiction des conversions implicites à l'objet? Non pas du tout.




3
votes

premier appel gc.collect () et puis vérifier faimètre.isalive . Si c'est vrai (c'est-à-dire, il n'a pas été collecté après avoir appelé gc.collect ), il y a une référence forte quelque part.


10 commentaires

+1 pour l'exactitude. Toutefois, si vous appelez GC.Collect pour vérifier les comptes de référence d'objet, vous appuierez des objets dans des générations ultérieures - les faire vivre plus longtemps si vous arrêtez jamais d'invoquer manuellement le GC. En tant que tel - c'est une mauvaise pratique.


Pas techniquement correct. Que forçant une collection de génération-zéro ne garantit pas que l'objet en question sera collecté: il aurait peut-être été promu dans une génération supérieure


Cela ne sera promu qu'une génération supérieure s'il y a encore des références exceptionnelles. Si le GC détermine qu'il n'y a pas de références, cela sera laissé seul ou collecté.


@Tim Robinson Ce n'est pas strictement vrai. Il y a une heuristique impliquée dans la promotion d'objets à des générations supérieures. Ce n'est pas quelque chose que vous pouvez compter maintenant. Et il n'est certainement pas documenté de ne pas changer demain. En outre, les objets jamais sont collectés sont un scénario valide (c'est-à-dire le collecteur de déchets NULL NULL un collecteur de déchets valide). Rien ne dit que le collecteur des ordures doit faire quoi que ce soit lorsque vous appelez collecter - c'est un détail de mise en œuvre interne.


@Ian: MSDN dit que GC.Collect "oblige une collecte immédiate des ordures de toutes générations". msdn.microsoft.com/en-us/library/xe0c2357.aspx


@ Dark CIDADE Le GC est autorisé à ne rien faire. En outre, parce que c'est enfilé, c'est une condition de course.


Où dit-il que le gc de .NET ne peut rien faire lorsque vous appelez GC.Collect ()? L'argument null GC de Chen n'est que théorique. Et je ne vois pas comment c'est une condition de race depuis GC.Collect () ne revient pas avant que cela soit terminé la collection.


@Mark CIDADE Il ne dit pas que le GC peut ne rien faire lorsque vous appelez gc.collect () ; ne dit pas non plus ce que le GC va faire. Il est dit "oblige une collecte immédiate des ordures de toutes générations."). Une optimisation qui est autorisée à exister là où elle ne fait rien ", d'accord, j'ai effectué les opérations de collecte - et j'ai collecté rien puisqu'il n'y a pas de pression de mémoire."


Remarque Vérification Isalive pour true est un conditon de course. Voir Remarques dans la documentation: "Parce qu'un objet pourrait potentiellement être récupéré pour la collecte des ordures immédiatement après que la propriété Isalive renvoie true, l'utilisation de cette propriété n'est pas recommandée, sauf si vous ne testez que pour une fausse valeur de retour."


Nous avons créé il y a presque 7 ans que ce n'est pas une méthode fiable.