イベントがどのようにメモリ リークを引き起こすかを理解しようとしています。この 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 フォーム アプリケーションで次のように使用しています。
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");
}
}
ご覧のとおり、Person クラスをインスタンス化し、UponWakingUp イベントをサブスクライブしました。このフォームにボタンがあります。ユーザーがこのボタンをクリックすると、イベントのサブスクライブを解除せずに、この Person インスタンスを null に設定します。次に、GC.Collect を呼び出して、ガベージ コレクションが実行されていることを確認します。ここにメッセージ ボックスを表示しているので、Windbg をアタッチして Form1 クラスによる参照のヘルプを参照できます。このクラス内では、そのイベントへの参照は表示されません (Form1 のデータが長すぎますが、Windbg の出力を以下に示します。私の質問に関連しています)。このクラスには Person クラスへの参照がありますが、null です。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