2010-07-21 3 views
1

Nous avons une classe d'événement qui a une référence d'une classe msgCorps:Comment indiquer au GC de nettoyer également un objet incorporé?

public class StatusEvent 
{ 
    MsgBody msgBody; 
    public StatusEvent(MsgBody body) 
    { 
     msgBody = body; 
    } 
.... 
} 

public class MsgBody 
{ 
    string s1; 
    string s2; 
..... 

} 

MsgBody classe est utilisé uniquement par StatusEvent. Aucun autre endroit MsgBody n'est référé. Lorsqu'une instance StatusEvent est créée, une instance MsgBody sera créée. Lorsqu'un objet StatusEvent est prêt pour le nettoyage, un objet MsgBody peut être nettoyé en toute sécurité.

Mais le résultat est le nettoyage MsgBody est loin derrière le StatusEvent. D'un résultat de profileur, j'ai trouvé qu'il n'y avait que 43 instances Live de StatusEvent mais il y avait 9 940 instances de MsgBody!

Existe-t-il un moyen de les lier ensemble et de rendre GC le nettoyage MsgBody lorsqu'il supprime StatusEvent?

grâce,

+0

Si ce que vous dites est vrai, alors lorsque 'StatusEvent' est collecté, l'instance' MsgBody' devrait être éligible pour le garbage collection. Y a-t-il des événements ou des délégués de rappel utilisés (ils contiennent aussi des références)? Je vois qu'il est passé dans le constructeur donc il est créé en dehors de la classe 'StatusEvent' => il y a peut-être un champ contenant la référence en dehors de la classe. –

Répondre

1

Si vous voulez la libération déterministe des ressources, StatusEvent doit mettre en œuvre IDisposable. Dans l'implémentation de la méthode IDisposable.Dispose, vous pouvez libérer toutes les ressources conservées. Dans votre cas, vous pouvez mettre l'instruction msgBody = null; à votre code. Etes-vous sûr qu'il n'y a aucun autre endroit où msgBody est stocké?

+0

Oui, je suis sûr qu'il n'y a pas d'autre endroit tenir le msgBody. – 5YrsLaterDBA

+0

Il n'est pas nécessaire d'implémenter IDisposable pour effacer une référence. Définir la référence à null peut rendre la référence interne éligible pour GC plus tôt que le propriétaire (elle peut déjà être éligible avant même qu'elle ne soit null, en fait), mais elle sera également éligible dès que l'objet parent n'est plus référencé . –

0

Normalement, le CPG devrait libérer automatiquement la mémoire dès que la mémoire est nécessaire ailleurs. Mais si vous voulez accélérer ce, vous pouvez appeler ce qui suit à la mémoire libre immidiately:

http://msdn.microsoft.com/en-us/library/system.gc.collect.aspx

+0

Cela aura probablement des effets négatifs sur l'exécution et n'est pas recommandé. –

+0

Parfois, il est préférable d'appeler system.gc.collect manuellement si vous savez que vous avez suffisamment de temps libre pour collecter, mais à l'avenir vous aurez beaucoup de travail à faire pour que le GC prenne le temps et la bande passante mémoire dont vous avez besoin. – Chris

+0

Non, ce n'est pas mieux. GC.Collect est dans le cadre pour une raison entièrement différente, à savoir permettre aux bibliothèques de nettoyer de grandes ressources avant que le GC soit «formé». Si vous faites cela parce que «vous savez que maintenant il y a suffisamment de temps libre», vous interrompez la formation GC et cela sera moins efficace. – Stilgar

0

Si le MsgBody n'a pas de l'accès aux ressources coûteuses, le GC prendra soin une fois que l'objet est hors de portée. Vous pouvez également définir msgBody=null;.

0

Si vous n'appelez pas GC.Collect(), tout dépendra du GC. Je ne pense pas qu'il existe un moyen d'enseigner GC comme vous le voulez.

Questions connexes