我想了解事件如何导致内存泄漏。我在this的stackoverflow问题中发现了一个很好的解释,但是当在Windg中查看对象时,我对结果感到困惑。首先,我有一个简单的课程,如下所示。为什么这不会导致内存泄漏事件未取消订阅
class Person
{
public string LastName { get; set; }
public string FirstName { get; set; }
public event EventHandler UponWakingUp;
public Person() { }
public void Wakeup()
{
Console.WriteLine("Waking up");
if (UponWakingUp != null)
UponWakingUp(null, EventArgs.Empty);
}
}
现在我在Windows窗体应用程序中使用这个类,如下所示。你可以看到,我instaniated人类和订阅UponWakingUp事件。我在这个表单上有一个按钮。当用户点击这个按钮时,我将这个Person实例设置为null,而不用取消订阅该事件。然后我打电话给GC.Collect以确保Garbade系列已经完成。我在此处显示一个消息框,以便我可以将Windbg附加到Form1类的引用帮助中,并且在此类中我没有看到对该事件的任何引用(Windbg输出如下所示,尽管Form1的数据太长,我正在显示与我的问题有关)。这个类有一个Person类的引用,但它是空的。基本上,这似乎不像内存泄漏给我,因为Form1没有任何对Person类的引用,即使它没有退订该事件。
我的问题是如果这确实会导致内存泄漏。如果不是,为什么不呢?
0:005> !do 0158d334
Name: WindowsFormsApplication1.Form1
MethodTable: 00366390
EEClass: 00361718
Size: 332(0x14c) bytes
File: c:\Sandbox\\WindowsFormsApplication1\WindowsFormsApplication1\bin\Debug\WindowsFormsApplication1.exe
Fields:
MT Field Offset Type VT Attr Value Name
619af744 40001e0 4 System.Object 0 instance 00000000 __identity
60fc6c58 40002c3 8 ...ponentModel.ISite 0 instance 00000000 site
619af744 4001534 b80 System.Object 0 static 0158dad0 EVENT_MAXIMIZEDBOUNDSCHANGED
**00366b70 4000001 13c ...plication1.Person 0 instance 00000000 John**
60fc6c10 4000002 140 ...tModel.IContainer 0 instance 00000000 components
6039aadc 4000003 144 ...dows.Forms.Button 0 instance 015ad06c button1
0:008> !DumpHeap -mt 00366b70
Address MT Size
total 0 objects
Statistics:
MT Count TotalSize Class Name
Total 0 objects
在这种情况下,Form1是Person类实例的源代码的列表器。你是说约翰会参考Form1?我现在完全困惑。 –
@palmsnow是的,'John.UponWakingUp'包含对包含对“Form1”的引用的委托的引用。否则提高这个事件是行不通的。 – svick
请参阅[本](http://csharpindepth.com/Articles/Chapter2/Events.aspx)文章以获取更多详细信息。顺便提一下,一个结构良好的问题+1。 –