J'ai une application qui présente des fuites de mémoire en raison d'événements qui ne sont pas détachés avant qu'une référence d'objet soit définie sur null. L'application est assez grande et il est difficile de trouver les fuites de mémoire en regardant le code. Je veux utiliser sos.dll pour trouver les noms des méthodes qui sont la source de fuites mais je suis bloqué. J'ai mis en place un projet de test pour démontrer le problème.Fuites de mémoire basées sur les événements C#
Ici, j'ai 2 classes, l'une avec un événement, et sur les écoutes à cet événement comme ci-dessous
namespace MemoryLeak
{
class Program
{
static void Main(string[] args)
{
TestMemoryLeak testMemoryLeak = new TestMemoryLeak();
while (!Console.ReadKey().Key.Equals('q'))
{
}
}
}
class TestMemoryLeak
{
public event EventHandler AnEvent;
internal TestMemoryLeak()
{
AnEventListener leak = new AnEventListener();
this.AnEvent += (s, e) => leak.OnLeak();
AnEvent(this, EventArgs.Empty);
}
}
class AnEventListener
{
public void OnLeak()
{
Console.WriteLine("Leak Event");
}
}
}
je casse dans le code, et le type de fenêtre intermédiaire
.load sos.dll
puis-je utiliser! dumpheap pour obtenir les objets sur le tas du type AnEventListener
!dumpheap -type MemoryLeak.AnEventListener
et je reçois la fo llowing
PDB symbol for mscorwks.dll not loaded
Address MT Size
01e19254 0040348c 12
total 1 objects
Statistics:
MT Count TotalSize Class Name
0040348c 1 12 MemoryLeak.AnEventListener
Total 1 objects
J'utilise! gcroot de comprendre pourquoi l'objet n'est pas des déchets collectés
!gcroot 01e19254
et obtenir les éléments suivants
!gcroot 01e19254
Note: Roots found on stacks may be false positives. Run "!help gcroot" for
more info.
Error during command: Warning. Extension is using a callback which Visual Studio
does not implement.
Scan Thread 5208 OSTHread 1458
ESP:2ef3cc:Root:01e19230(MemoryLeak.TestMemoryLeak)->
01e19260(System.EventHandler)->
01e19248(MemoryLeak.TestMemoryLeak+<>c__DisplayClass1)->
01e19254(MemoryLeak.AnEventListener)
Scan Thread 7376 OSTHread 1cd0
je peux voir maintenant le gestionnaire d'événements qui est la source de la fuite. Je l'utilise! Faire pour regarder les champs du gestionnaire d'événements et obtenir
!do 01e19260
Name: System.EventHandler
MethodTable: 65129dc0
EEClass: 64ec39d0
Size: 32(0x20) bytes
(C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
MT Field Offset Type VT Attr Value Name
65130770 40000ff 4 System.Object 0 instance 01e19248 _target
6512ffc8 4000100 8 ...ection.MethodBase 0 instance 00000000 _methodBase
6513341c 4000101 c System.IntPtr 1 instance 0040C060 _methodPtr
6513341c 4000102 10 System.IntPtr 1 instance 00000000 _methodPtrAux
65130770 400010c 14 System.Object 0 instance 00000000 _invocationList
6513341c 400010d 18 System.IntPtr 1 instance 00000000 _invocationCount
Alors maintenant, je peux voir le pointeur sur la méthode qui n'est pas détaché
0040C060 _methodPtr
mais comment puis-je obtenir le nom de cette méthode?
S'il vous plaît voir ma réponse à cette question pour savoir comment obtenir ce que _methodPtr pointe vers http://stackoverflow.com/questions/3668642/get-method-name-form-delegate-with-windbg/3682594 # 3682594 –
Wow, c'est une jolie tho explication grossière d'un examen de débogage. Upvote pour avoir pris le temps de poster un exemple détaillé - et il pourrait être utile aux autres à l'avenir. Je vais mettre ceci en signet. –