一个内存泄露的例子

内存泄露案例分析:子窗口事件注册与释放的重要性
本文通过一个具体的内存泄露例子,详细分析了子窗口在父窗口中注册事件及其释放过程对内存管理的影响。展示了静态字段未及时清理导致的内存泄露问题,并强调了事件注册与释放的一致性对于避免内存泄漏的关键性。

主窗口:

 

namespace WindowsFormsApplication17

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

 

public event EventHandler Form1Test;

 

private void button1_Click(object sender, EventArgs e)

{

var sb = new StringBuilder();

sb.AppendLine(GetTotalMemory());

for (int i = 0; i < 5; i++)

{

var form2 = new Form2() { Parent = this };

form2.Form2Test += new EventHandler(form2_Form2Test); // register event in Form2 doesn't cause memory leak.

form2.Show();

form2.Close();

GC.Collect();

sb.AppendLine(GetTotalMemory());

}

 

MessageBox.Show(sb.ToString());

}

 

void form2_Form2Test(object sender, EventArgs e)

{

}

 

public static string GetTotalMemory()

{

// bytes in current process' managed heap.

return GC.GetTotalMemory(true) / 1024 + " K";

}

}

}

 

子窗口:

namespace WindowsFormsApplication17

{

public partial class Form2 : Form

{

public Form2()

{

InitializeComponent();

}

 

private byte[] strs = new byte[50 * 1024 * 1024]; // 50MB

//You can very well make a static

//member eligible for a collection by setting it to null. Otherwise, a static

//member would last for the life of the appdomain in which it lies.

private static byte[] strss = new byte[20 * 1024 * 1024]; // 20MB

 

public event EventHandler Form2Test;

public Form1 Parent { get; set; }

 

protected override void OnLoad(EventArgs e)

{

Parent.Form1Test += new EventHandler(Form2_Form1Test);

base.OnLoad(e);

}

 

void Form2_Form1Test(object sender, EventArgs e)

{

}

 

protected override void OnClosing(CancelEventArgs e)

{

base.OnClosing(e);

// if don't unregister this event from parent, causes memory leak.

Parent.Form1Test -= new EventHandler(Form2_Form1Test);

}

}

}

 

静态字段strss在调用了GC.Collect();后还是存在的,它不会被回收。

在子form中注册父form的事件,如果不取消注册会导致内存泄露。

相反,在父form中注册子form的事件,不会导致内存泄露。

如果注释掉Parent.Form1Test -= new EventHandler(Form2_Form1Test);

运行结果如下,内存泄露了:

 

如果执行这句代码,运行结果如下,内存不泄露:

 

posted on 2012-04-23 17:00 cutebear 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/bear831204/archive/2012/04/23/2466686.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值