2012-07-08 135 views
1

我有一个大的WinForm类,它从一个小像这样的呼吁:C#WinForm的内存泄漏

void login() 
    {   
     mainForm f1 = new mainForm();     
     f1.ShowDialog(); 
    } 

的MainForm的将登录(我检查它在任务管理器)之后采取大量内存。关闭mainForm后,程序返回登录表单。在这一步我再次检查任务管理器,看看我的程序还没有发布mainForm使用的内存。一些登录后,我的程序崩溃,并显示“内存不足”错误。

我不得不说我测试了f1.Dispose(),f1 = null,GC.Collect()和我发现的每一个其他方法。

当我关闭登录表单(在Application.Run利用其出发类)

我要摧毁MainForm的实例(F1)这种形式的所有资源,就好像当它只会释放内存我关闭了该程序。

+0

你说你已经加了'f1.Dispose(); f1 = null; GC.Collect(); * * *之后*'f1.ShowDialog();'它不起作用?此外,它是在调试还是发布? – 2012-07-08 14:16:40

+0

静态事件处理程序的味道 – 2012-07-08 14:18:23

+0

是的,我检查了我在不同论坛中找到的所有方法。并没有发生。 – oMatrix 2012-07-08 14:29:03

回答

2

夫妇的想法:

+0

我之前使用语句检查过,但它没有帮助。关于其他控件,我只是使用.Net标准控件和我自己的控件,我应该说我也有一些非托管代码。奇怪的是,当我关闭mainForm时,我没有看到我的程序在内存使用方面有任何改变。我认为至少它应该释放一部分内存。关于windbg和sos,不,我会检查它们。 – oMatrix 2012-07-08 14:38:50

+0

谢谢,我使用了内存分析器,发现了一些问题。我认为需要一些时间才能找到所有问题。 – oMatrix 2012-07-09 10:40:08

1

也许MainForm的产生对自身的引用显示时,检查任何引用/代表/事件,它分配并确保它们是未注册时的MainForm完成后,或将事件处理程序(即应用程序事件)到一个单独的类。

到目前为止100%的时间我“发现一个.NET内存泄漏”,它没有!处置所有一次性物品,观察你使用静态参考文件所做的事情,不要重复事件订阅,并在可能的情况下整理它们。

使用SOS作为mouters在运行后检查mainform类上的gcroots,并在调用GC.Collect(3)几次后,一旦找到引用的地方,就应该找到该bug。

3

不太确定OOM与登录表单有什么关系。而且,关闭或处理表单会降低Taskmgr.exe报告的内存使用量。

但是你肯定是做错了。对话框在Winforms中的处理方式不同,它不会像使用Show()显示的窗体那样自动放置。通常情况下,您想要在用户输入对话框后输入的任何内容,这在对话框处理时会很危险。所以你必须自己做。正确的模式是:

using (mainForm f1 = new mainForm()) { 
     if (f1.ShowDialog() == DialogResult.Ok) { 
      // Retrieve data entered by user and do something with it 
      //... 
     } 
    } 

随着使用声明确保后检索到的对话结果的对话实例得到处理。

+0

使用声明并没有帮助我。你的代码正是我所做的。 – oMatrix 2012-07-08 15:03:25

+0

这就是我在第一句中告诉你的。你没有记录关于OOM状况的任何信息。我只能假设你的代码与其他地方的代码类似,当然也是触发OOM条件的一种方式。如果您不知道泄漏可能位于何处,请使用内存分析器。 – 2012-07-08 15:08:58