2017-02-01 20 views
0

我有一个类,其中,基于某个事件,我initialize一个新的基于表单的对话框和initialize它。这个基于表单的对话框里面有其他控件。C#表单应用程序中的内存泄露

dialog已关闭时,我清除并处理掉在表单中创建的所有控件。不幸的是,似乎有些东西没有被处置,或者在删除之后仍留在记忆中。

形泵

class someClass 
{ 
    System.Timers.Timer someTimer; 
    public void CallToChildThread(Object stateInfo) 
    { 
     // check some event 
     // if true, fire event 
    } 
    someClass() 
    { 
      someTimer= new System.Threading.Timer(CallToChildThread, 
            autoEvent, 1000, 250); 
      _show += new EventHandler(eventCheck); 
    } 
    void eventCheck() 
    { 
     formClass formClassObject = new formClass(); //create form 
     formClassObject.someFunction(); // has some other function and does a showDialog on self 
     formClassObject.Dispose(); 
     formClassObject = null; 
    } 
} 

里面的formClass对象,在获得FormClosed事件,我处理了所有的控件和控件对象中的控制范围内,但仍有noticable内存泄漏。

Form类

public partial class formClass 
{ 
    //Initialize a bunch of managed resources to null 
    someOtherForm form2; 
    someOtherForm form3; 
    //connect some events on child forms to buttons on this form object 
    this.form2.cancelButtonClicked += someFunction; 
    this.form3.cancelButtonClicked += someFunction; 
    // Form closed Event 
    private void formClass_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     //set form2 and form3 visibility to false 
     // clear AND dispose all controls of form2 
     // clear AND dispose all controls of form3 
     //set form2 and form3 to null 
     // clear AND dispose off all controls of formClass 
     // Dispose this (formClass) object 
    } 
} 

有没有用我初始化了表单对象的方式可能的问题?那些没有被处置?

+3

为什么你认为有内存泄漏?请注意,垃圾收集本身决定_when_实际释放内存。这种情况不一定是立即发生,但最终可以在gc发现没有足够的内存来完成下一个分配请求时完成。顺便说一句:如果你处理表单,它将自己处理所有的控件,不需要手动完成。 –

+0

什么样的行为导致你相信存在内存泄漏? – tonythewest

+1

尝试处置计时器以及表单对象? –

回答

1

请看这里:Memory Leaks in Winforms application

尝试删除事件处理程序(_show)配置真正具有子窗体配置的内存之前。

+0

允许我问什么可能是一个愚蠢的问题......事件_show如何影响formClass的对象?这只是someClass中的一个事件(它不是表单),当定时器内条件满足时就会发出这个事件。另外,如果我放弃此事件,_show,那么计时器稍后会发出什么信号? – user1173240

+0

@ user1173240我不确定,因为在响应中没有看到您的form.someFunction方法,但为了正确检测问题,我需要查看整个formClass对象。处理或关闭表单只会删除UI元素。如果你的'formClass'中有任何变量,对象,事件处理等等,你需要在表单中调用'.Dispose()'''的FormClosed'事件。这是我最好的猜测,没有看到我自己的所有代码。 –

+0

我已经添加了一些代码,它基本上描述了我在formClass formClosed事件中所做的事情。 – user1173240

0

您没有删除事件处理程序,这可能是泄漏的来源。 也许你应该让某个类一次性并删除Dispose方法中的处理程序。

你如何确认有泄漏?垃圾收集器可能会延迟运行,给人的感觉是内存不被收集。您可以显式调用GB每个表单处理后,看看会发生什么:

formClassObject.Dispose(); 

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 

其他一些提示:

创建可以抛出异常,并没有妥善处理的形式。 既然你创建模态对话框(调用的ShowDialog),你应该使用使用模式

using (formClass formClassObject = new formClass()) 
{ 
    formClassObject.someFunction(); 
} 

可以使用.NET剖析排查泄漏。

看到这个职位的备选方案:

What Are Some Good .NET Profilers?

+0

认为存在泄漏,因为每次我发起创建新表单并初始化控件的事件时,内存都会显着增加。另外,应用程序的“任务管理”中的用户对象计数器会上升。如果我打开10个表单,内存会增加很多,所以用户对象也会增加,但即使关闭所有表单,无论应用程序运行多长时间,也不会关闭。用户对象计数下降了一点,但仍然很高。我认为这可能是UI的数据源的问题,但是所有的对象和控件都是托管的,并且应该通过表单关闭消失 – user1173240

+0

这很有道理。可能你可以用.NET Profiler来固定这个问题,或者通过逐渐减轻你的表单类来做最小的事情(如果可能的话)。通常情况下,如果检测到大量内存泄漏,则数据源处理不当(正如您已经怀疑的那样)。 – GeorgeT