Mam aplikację, która ma pewne wycieki pamięci ze względu na to, że zdarzenia nie są odłączane, zanim odwołanie do obiektu jest ustawione na wartość null. Wniosek jest dość duży i trudno jest znaleźć wycieki pamięci, patrząc na kod. Chcę użyć sos.dll, aby znaleźć nazwy metod, które są źródłem przecieków, ale utknąłem. Przygotowałem projekt testowy, aby zademonstrować problem.C# Wady pamięci oparte na zdarzeniach
Tutaj mam 2 klas, jeden ze zdarzeniem, a na słucha tego wydarzenia poniżej
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");
}
}
}
złamię do kodu, w pośredniej okna typu
.load sos.dll
następnie używam! dumpheap, aby uzyskać obiekty na stercie typu AnEventListener
!dumpheap -type MemoryLeak.AnEventListener
i otrzymuję 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
używam! gcroot wypracować dlaczego obiekt nie jest śmieci zbierane
!gcroot 01e19254
i uzyskać następujące
!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
mogę teraz zobaczyć obsługi zdarzeń, który jest źródło wycieku. Używam! Zrobić, aby spojrzeć na dziedzinie obsługi zdarzeń i dostać
!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
Więc teraz widzę wskaźnik do metody, która nie jest oderwane
0040C060 _methodPtr
ale jak mogę dostać nazwa tej metody?
Proszę zobaczyć moją odpowiedź na to pytanie, jak uzyskać to, co _methodPtr wskazuje na http://stackoverflow.com/questions/3668642/get-method-name-form-delegate-w-windbg/3682594 # 3682594 –
Wow, to jest piękne przybliżone objaśnienie badania debugowania. Weź udział w zajęciach, aby poświęcić trochę czasu na opublikowanie szczegółowego przykładu - i może on zostać wykorzystany w przyszłości przez innych. Zakładam to. –