我想了解事件如何导致内存泄漏。 我发现了一个很好的解释在这个计算器的问题,但看着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窗体应用程序如下使用这个类。
public partial class Form1 : Form
{
Person John = new Person() { LastName = "Doe", FirstName = "John" };
public Form1()
{
InitializeComponent();
John.UponWakingUp += new EventHandler(John_UponWakingUp);
}
void John_UponWakingUp(object sender, EventArgs e)
{
Console.WriteLine("John is waking up");
}
private void button1_Click(object sender, EventArgs e)
{
John = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
MessageBox.Show("done");
}
}
正如你所看到的,我instaniated Person类和订阅UponWakingUp事件。 我有这个表单上的按钮。 当用户点击这个按钮,我这个人实例设置为空,而不取消订阅的事件。 然后,我调用GC.Collect,以确保被执行了Garbade集合。 我在这里显示一个消息框,这样我就可以连接WinDbg通过Form1类看起来引用的帮助和这个类中我没有看到该事件的任何引用(WinDBG的输出如下所示虽然Form1中有太长的数据,我展示有关我的问题)。 这个类有Person类的引用,但它是空的。 基本上,这看起来像内存泄漏给我不为Form1不具有Person类的任何引用甚至thouh它没有退订的事件。
我的问题是,如果这样做导致内存泄漏。 如果不是,为什么不呢?
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