मैं यह समझने की कोशिश कर रहा हूं कि ईवेंट मेमोरी रिसाव कैसे कर सकता है। मुझे this स्टैक ओवरफ्लो प्रश्न पर एक अच्छी व्याख्या मिली लेकिन विंडग में ऑब्जेक्ट्स को देखते समय, मुझे परिणाम से भ्रमित हो रहा है। शुरू करने के लिए, मेरे पास निम्नानुसार एक साधारण वर्ग है।जब ईवेंट की सदस्यता समाप्त नहीं होती है तो यह स्मृति रिसाव का कारण नहीं बनता है
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);
}
}
अब मैं इस वर्ग का उपयोग विंडोज़ फॉर्म एप्लिकेशन में निम्नानुसार कर रहा हूं।
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");
}
}
जैसा कि आप देख सकते हैं, मैंने पर्सन क्लास को उपनिवेशित किया और उपनवैकअप ईवेंट की सदस्यता ली। मेरे पास इस फॉर्म पर एक बटन है। जब उपयोगकर्ता इस बटन पर क्लिक करता है, तो मैंने ईवेंट को अन-सदस्यता के बिना इस व्यक्ति का उदाहरण शून्य पर सेट किया है। फिर मैं जीसी को कॉल करता हूं। यह सुनिश्चित करने के लिए चयन करें कि गारबैड संग्रह किया गया है। मैं यहां एक संदेश बॉक्स दिखा रहा हूं ताकि मैं फॉर्म 1 कक्षा द्वारा संदर्भ सहायता देखने के लिए विंडबग को संलग्न कर सकूं और इस कक्षा के भीतर मुझे उस घटना का कोई संदर्भ दिखाई नहीं दे रहा है (विंडबग आउटपुट नीचे दिखाया गया है हालांकि फॉर्म 1 में बहुत लंबा डेटा है, मैं प्रदर्शित कर रहा हूं मेरे प्रश्न से संबंधित)। इस वर्ग में व्यक्ति वर्ग का संदर्भ है लेकिन यह शून्य है। असल में यह मेरे लिए स्मृति रिसाव की तरह प्रतीत नहीं होता है क्योंकि फॉर्म 1 में व्यक्ति वर्ग का कोई संदर्भ नहीं है, भले ही आपने ईवेंट की सदस्यता नहीं ली हो।
मेरा सवाल यह है कि अगर यह स्मृति रिसाव का कारण बनता है। यदि नहीं, तो क्यों नहीं?
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
इस मामले में फॉर्म 1 स्रोत वर्ग की सूची है जो व्यक्ति वर्ग उदाहरण है। क्या आप कह रहे हैं कि जॉन के पास फॉर्म 1 का संदर्भ होगा ???? मैं अब पूरी तरह से उलझन में हूँ। –
@palmsnow हाँ, 'John.UponWakingUp' में एक प्रतिनिधि का संदर्भ है जिसमें' फॉर्म 1 'का संदर्भ शामिल है। यह घटना बढ़ाना अन्यथा काम नहीं कर सका। – svick
अधिक जानकारी के लिए [यह] (http://csharpindepth.com/Articles/Chapter2/Events.aspx) आलेख देखें। एक अच्छी तरह से संरचित प्रश्न के लिए बीटीडब्ल्यू +1। –