有没有好的办法试验是否存在内存泄漏?

phommy 2014-11-21 10:01:02
听说某些情况下,如果手工+=了事件但不做-=会造成内存泄漏,想知道以下代码是不是属于这类情况,要怎么测试呢?



void btnExit_Click(object sender, EventArgs e)
{
var frm = new ConfirmForm(this);
using (frm)
{
frm.ShowDialog();
frm.Disposed += frm_Disposed; //想测试如果手动+=了事件但不做-=会不会造成内存泄漏,要如何做?
}
Close();
}

void frm_Disposed(object sender, EventArgs e) { MessageBox.Show("disposed"); }
...全文
127 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/390662973?page=1#post-396278904 测试时,不需要一开始就针对具体的子控件、组件、对象进行测试。例如我们可以先把一个窗体放入“内存溢出测试”,然后如果这个窗体在使用完毕20秒钟还没有被GC回收,我们才需要仔细看这个窗体里边有什么需要检测的。往往此时不需要再写测试,而用肉眼就能发现有问题的语句了。
winnowc 2014-11-21
  • 打赏
  • 举报
回复
这种造成内存泄漏的原因是delegate内部引用了方法所在的对象(Delegate类里面的_target变量),当然如果是匿名方法引用了外部变量,那还会生成一个类来维持这些引用(闭包)。 如果事件的提供方是一个长时间存在的对象,而事件的使用方生命周期比较短,并且数量会持续增加。如果它把自己挂到长时间存在的提供方上,就无法被回收了。所以这种情况下需要及时移除delegate,把引用链断开。 首先自己每次写+=的时候要考虑清楚双方的生命周期,知道+=是相当于把this添加到了提供方里。如果这个自己考虑不清楚,用工具检测有点麻烦,工具可以帮忙追踪托管对象的创建和释放,然后进行多次快照(快照时会进行完整GC),比较快照之间的变化,在GC后还存活的对象里面找自己认为应该已经释放,但是仍然存在的东西。最后可以按引用链查找被引用的原因。 这里这里是两个.net上的memory profiler工具检查内存泄漏的教程。微软也有简单点的CLRProfiler做同样的事情。
敌敌畏耶 2014-11-21
  • 打赏
  • 举报
回复

var frm = new ConfirmForm(this);
            while (true)
            {
                frm.Disposed +=this.frm_Disposed; 
                Thread.sleep(5);
            }

111,094

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧