У меня есть приложение, которое имеет некоторые утечки памяти из-за того, что события не отсоединяются до того, как для ссылки на объект установлено значение null Приложение довольно большое, и трудно найти утечки памяти, глядя на код. Я хочу использовать sos.dll, чтобы найти имена методов, которые являются источником утечек, но я застреваю. Я создал тестовый проект для демонстрации проблемы.
Здесь у меня есть 2 класса, один с событием, и слушает это событие, как показано ниже
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");
}
}
}
врываюсь в код, а в промежуточном окне набираю
.load sos.dll
затем я использую! Dumpheap, чтобы получить объекты в куче типа AnEventListener
!dumpheap -type MemoryLeak.AnEventListener
и я получаю следующее
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
Я использую! Gcroot, чтобы выяснить, почему объект не подвергается сборке мусора
!gcroot 01e19254
и получите следующее
!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
Теперь я вижу обработчик событий, который является источником утечки. Я использую! Сделать, чтобы посмотреть на
поля обработчика событий и получаем
!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
Итак, теперь я вижу указатель на метод, который не отключается
0040C060 _methodPtr
но как мне получить название этого метода?