Trouver des références à l'objet lors de l'exécution
J'ai un objet, qui vit pour toujours. Je suis deleteing toutes les références que je peux voir, après qu'il l'aide, mais il ne collecte pas encore. Son cycle de vie est assez sophistiquée, donc je ne peux pas être sûr que toutes les références à été effacé.
if ( container.Controls.Count > 0 )
{
var controls = new Control[ container.Controls.Count ];
container.Controls.CopyTo( controls, 0 );
foreach ( var control in controls )
{
container.Controls.Remove( control );
control.Dispose();
}
controls = null;
}
GC.Collect();
GC.Collect(1);
GC.Collect(2);
GC.Collect(3);
Comment puis-je savoir quelles sont les références-t-il encore? Pourquoi est-il recueilli?
Montre-nous ton code et on peut peut-être aider. Gardez à l'esprit que la collecte des ordures n'est pas forcément immédiatement.
Et je pense que la vraie question est, pourquoi vous inquiéter? Si vous êtes à l'aide des ressources disponibles, d'en Disposer quand vous ne l'utilisez pas plus de nettoyer non géré les ressources du système, et attention à la chaîne de stage.
Le code est: si ( récipient.Les contrôles.Count > 0 ) { var contrôles = nouveau Contrôle[ conteneur.Les contrôles.Count ]; conteneur.Les contrôles.CopyTo( contrôles, 0 ); foreach ( var contrôle dans les contrôles ) { conteneur.Les contrôles.Supprimer( de contrôle ); le contrôle.Dispose(); } contrôles = null; } GC.Collect(); GC.Collecter(1); GC.Collecter(2); GC.Collecter(3); Mais il est encore en mémoire. Donc ça veut dire, qu'il l'acier ont des racines. Comment puis-je trouver cette racines?
Êtes-vous sûr que c'est dans la mémoire? La machine virtuelle ne peut pas donner de la mémoire qu'il a utilisés.
Désolé pour le formatage, Le code est: "si ( le contenant.Les contrôles.Count > 0 ) { var contrôles = nouveau Contrôle[ conteneur.Les contrôles.Count ]; conteneur.Les contrôles.CopyTo( contrôles, 0 ); foreach ( var contrôle dans les contrôles ) { conteneur.Les contrôles.Supprimer( de contrôle ); le contrôle.Dispose(); } contrôles = null; } GC.Collect(); GC.Collecter(1); GC.Collecter(2); GC.Collecter(3); " Mais c'est encore en mémoire. Donc ça veut dire, qu'il l'acier ont des racines. Comment puis-je trouver cette racines?
Et je pense que la vraie question est, pourquoi vous inquiéter? Si vous êtes à l'aide des ressources disponibles, d'en Disposer quand vous ne l'utilisez pas plus de nettoyer non géré les ressources du système, et attention à la chaîne de stage.
Le code est: si ( récipient.Les contrôles.Count > 0 ) { var contrôles = nouveau Contrôle[ conteneur.Les contrôles.Count ]; conteneur.Les contrôles.CopyTo( contrôles, 0 ); foreach ( var contrôle dans les contrôles ) { conteneur.Les contrôles.Supprimer( de contrôle ); le contrôle.Dispose(); } contrôles = null; } GC.Collect(); GC.Collecter(1); GC.Collecter(2); GC.Collecter(3); Mais il est encore en mémoire. Donc ça veut dire, qu'il l'acier ont des racines. Comment puis-je trouver cette racines?
Êtes-vous sûr que c'est dans la mémoire? La machine virtuelle ne peut pas donner de la mémoire qu'il a utilisés.
Désolé pour le formatage, Le code est: "si ( le contenant.Les contrôles.Count > 0 ) { var contrôles = nouveau Contrôle[ conteneur.Les contrôles.Count ]; conteneur.Les contrôles.CopyTo( contrôles, 0 ); foreach ( var contrôle dans les contrôles ) { conteneur.Les contrôles.Supprimer( de contrôle ); le contrôle.Dispose(); } contrôles = null; } GC.Collect(); GC.Collecter(1); GC.Collecter(2); GC.Collecter(3); " Mais c'est encore en mémoire. Donc ça veut dire, qu'il l'acier ont des racines. Comment puis-je trouver cette racines?
OriginalL'auteur er-v | 2009-09-24
Vous devez vous connecter pour publier un commentaire.
Essayez d'utiliser un memory profiler, (par exemple,les fourmis) il vous dira ce qui est maintenant l'objet vivant. En essayant de 2e suppose que ce type de problème est très dur.
Rouge-porte donne 14 jours d'essai qui devrait être plus alors assez de temps de virer de bord vers le bas ce problème et de décider si un memory profiler vous donne la valeur à long terme.
Il y a beaucoup d'autres profileurs de mémoire sur le marché (par exemple .NET Memory Profiler) la plupart d'entre eux ont des essais gratuits, cependant j'ai trouvé que le Red-Gate outils sont faciles à utiliser, ont tendance à essayer en premier.
Ils ont aussi quelques gratuit des vidéos de formation (et documents), etc qui expliquent comment l' .net garbage collector œuvres que vous pourriez trouver utiles.
votre objet peut avoir été recueillis, mais la mémoire peut ne pas avoir été remis en état par Windows. Le cadre n'a pas de retour de la mémoire pour le système d'exploitation.
Merci. Memory profiler est la chose dont j'avais besoin.
OriginalL'auteur Ian Ringrose
Vous aurez à utiliser Windbg et Sosex extension.
La
!DumpHeap
et!GCRoot
commandes peuvent vous aider à identifier l'instance, et tous les autres références que la garder vivante.OriginalL'auteur Romain Verdier
J'ai résolu un problème similaire avec l'extension SOS (qui apparemment ne fonctionne pas plus avec Visual Studio 2013, mais qui fonctionne bien avec les anciennes versions de Visual Studio).
J'ai utilisé le code suivant pour obtenir l'adresse de l'objet pour lequel je voulais suivre les références:
et puis, dans Visual Studio 2012 fenêtre lors de l'exécution dans le débogueur, type:
qui va charger le
SOS.dll
extension.Vous pouvez ensuite utiliser
GetAddress(x)
pour obtenir l'adresse hexadécimale de l'objet (par exemple8AB0CD40
), et ensuite utiliser:pour le vidage de l'objet et de trouver toutes les références à l'objet.
Il suffit de garder à l'esprit que si le GC s'exécute, il peut changer l'adresse de l'objet.
OriginalL'auteur Pierre Arnaud
J'ai été en utilisant .NET Profileur de Mémoire pour faire un peu de sérieux le profilage de la mémoire sur un de nos projets. C'est un excellent outil pour rechercher dans la gestion de la mémoire de votre application. Je ne suis pas payé pour cette info 🙂 mais ça m'a beaucoup aidé.
OriginalL'auteur Bjorn Bailleul
De la collecte des déchets .NET n'est pas une méthode de comptage (comme COM), mais un mark-and-sweep mise en œuvre. Fondamentalement, la GC s'exécute au "hasard" des moments où il se sent le besoin de le faire, et la collection d'objets est donc pas déterministe.
Cependant, vous pouvez déclencher manuellement une collection (GC.Collect()), mais vous pourriez avoir à attendre pour les finaliseurs à exécuter puis (GC.WaitForPendingFinalizers()). Ce faisant, dans une production, d'application, cependant, n'est pas recommandée, car elle peut influer sur l'efficacité de la gestion de la mémoire (GC tourne trop souvent, ou attend les finaliseurs à exécuter). Si l'objet existe toujours, il a toujours fait certains vivent de référence quelque part.
OriginalL'auteur Lucero
Il n'est pas recueilli parce que vous n'avez pas supprimé toutes les références à celui-ci. Le GC ne marquer des objets de collection si ils n'ont pas de racines dans l'application.
Quels moyens utilisez-vous pour vérifier la GC pour voir si elle a recueilli votre objet?
OriginalL'auteur Andrew Hare