2017-02-01 21 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